Skip to main content

harmos_storage/
file_hash.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10// Hash A Bounded File Range Without Retaining The Complete Payload.
11
12/* === Modules === */
13
14/* === Re-Exports === */
15
16/* === Imports === */
17
18// Standard Library Imports
19
20// Third Party Imports
21use sha2::{Digest, Sha256};
22
23// Local Imports
24use crate::{Result, StorageManager};
25use harmos_domain::model::storage::files::FileHash;
26use harmos_domain::operations::storage::{HashFile, ReadFile};
27
28/* === Constants === */
29
30/* === Macros === */
31
32/* === Type Aliases === */
33
34/* === Structs === */
35
36/* === Enums === */
37
38/* === Traits === */
39
40/* === Implementations === */
41
42impl<C> StorageManager<C> {
43    pub async fn hash_file(&self, request: HashFile) -> Result<FileHash> {
44        let context = crate::execution::Context::current();
45        let span = context.sync(|| tracing::debug_span!("storage.file.hash_file", outcome = "cancelled"));
46        context
47            .result(span, async {
48                let mut reader = self.read_file(ReadFile { source: request.source, range: request.range }).await?;
49                let mut hash = Sha256::new();
50                let local = reader.is_local();
51                while let Some(batch) = reader.next().await? {
52                    if local {
53                        hash.update(batch.bytes());
54                    }
55                }
56                let completion = reader.completion()?;
57                Ok(reader.stored_hash()?.unwrap_or_else(|| FileHash { bytes_read: completion.bytes, sha256: hash.finalize().into() }))
58            })
59            .await
60    }
61}
62
63/* === Public Functions === */
64
65/* === Private Functions === */
66
67/* === Tests === */