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