Skip to main content

harmos_operations/storage/
hash_file.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10// HashFile Declaration.
11
12/* === Modules === */
13
14/* === Re-Exports === */
15
16/* === Imports === */
17
18// Standard Library Imports
19
20// Third Party Imports
21
22// Local Imports
23use super::IO_POLICY;
24use harmos_domain::MemorySize;
25use harmos_domain::model::storage::codec::{Nested, product};
26use harmos_domain::model::storage::files::{ByteRange, FileHash, FileSource};
27use harmos_domain::operations::ReplaySafety;
28#[cfg(feature = "runtime")]
29use harmos_storage::{ErasedCatalog, StorageManager};
30
31/* === Constants === */
32
33/* === Macros === */
34
35product!(HashFile {
36    source: Nested<FileSource> => 1,
37    range: Nested<ByteRange> => 2,
38});
39
40/* === Type Aliases === */
41
42/* === Structs === */
43
44#[harmos::operation(harmos_path = crate, resources = [StorageManager<ErasedCatalog>], codec = manual,
45    id = "storage.hash_file",
46    response = FileHash,
47    policy = IO_POLICY,
48    visibility = Shared,
49    replay = ReplaySafety::Idempotent,
50    grpc(package = "harmos.storage.v1", service =  "Storage", method =  "HashFile"),
51    grant = Self::grant_for)]
52#[derive(Clone, Debug, PartialEq, Eq)]
53pub struct HashFile {
54    pub source: FileSource,
55    pub range: ByteRange,
56}
57
58/* === Enums === */
59
60/* === Traits === */
61
62/* === Implementations === */
63
64impl HashFile {
65    fn grant_for(request: &HashFile) -> Option<harmos_domain::plugin::Grant> {
66        request.source.grant_scope().map(|scope| harmos_domain::plugin::Grant::of(<Self as harmos_domain::OperationDeclaration>::ID, scope))
67    }
68}
69
70impl MemorySize for HashFile {
71    fn memory_size(&self) -> usize {
72        std::mem::size_of::<Self>()
73            .saturating_add(self.source.memory_size().saturating_sub(std::mem::size_of_val(&self.source)))
74            .saturating_add(self.range.memory_size().saturating_sub(std::mem::size_of_val(&self.range)))
75    }
76}
77
78#[cfg(feature = "runtime")]
79mod execution {
80
81    // HashFile Runtime Handler.
82
83    // Standard Library Imports
84
85    // Third Party Imports
86
87    // Local Imports
88    use crate::{Error, Result};
89    use harmos_domain::model::storage::files::FileHash;
90    use harmos_sdk::operations::Operation;
91
92    impl Operation for super::HashFile {
93        type Error = Error;
94
95        #[tracing::instrument(target = "harmos::storage", name = "storage.operation.hash_file", level = "trace", skip_all)]
96        async fn run(self, context: harmos_sdk::Context<'_, Self>) -> Result<harmos_sdk::operations::Response<FileHash>> {
97            let storage = context.resource::<harmos_storage::StorageManager<harmos_storage::ErasedCatalog>>();
98
99            Ok(storage
100                .hash_file(harmos_storage::FileRead {
101                    source: self.source.clone(),
102                    range: self.range,
103                })
104                .await?
105                .into())
106        }
107
108        fn classify(error: &Error) -> harmos_sdk::operations::FailureKind {
109            crate::storage::classify(error)
110        }
111    }
112}
113
114/* === Public Functions === */
115
116/* === Private Functions === */
117
118/* === Tests === */