Skip to main content

harmos_operations/storage/
list_directory.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// Third Party Imports
18// Local Imports
19use super::IO_POLICY;
20use harmos_domain::MemorySize;
21use harmos_domain::model::storage::codec::{Nested, product};
22use harmos_domain::model::storage::{DirectoryCompletion, DirectoryEntry, DirectorySelection};
23use harmos_domain::operations::ReplaySafety;
24#[cfg(feature = "runtime")]
25use harmos_storage::{ErasedCatalog, StorageManager};
26
27/* === Constants === */
28
29/* === Macros === */
30
31product!(ListDirectory { selection: Nested<DirectorySelection> => 1 });
32
33/* === Type Aliases === */
34
35/* === Structs === */
36
37#[harmos::operation(harmos_path = crate, resources = [StorageManager<ErasedCatalog>], codec = manual,
38    id = "storage.list_directory",
39    response = DirectoryCompletion,
40    policy = IO_POLICY,
41    output = DirectoryEntry,
42    visibility = Shared,
43    replay = ReplaySafety::Idempotent,
44    grpc(package = "harmos.storage.v1", service =  "Storage", method =  "ListDirectory"))]
45#[derive(Clone, Debug, PartialEq, Eq)]
46pub struct ListDirectory {
47    pub selection: DirectorySelection,
48}
49
50/* === Enums === */
51
52/* === Traits === */
53
54/* === Implementations === */
55
56impl MemorySize for ListDirectory {
57    fn memory_size(&self) -> usize {
58        std::mem::size_of::<Self>().saturating_add(self.selection.memory_size().saturating_sub(std::mem::size_of_val(&self.selection)))
59    }
60}
61
62#[cfg(feature = "runtime")]
63mod execution {
64
65    // Finite Storage Query Operation
66
67    // Standard Library Imports
68    // Third Party Imports
69    // Local Imports
70    use crate::{Error, Result};
71    use harmos_domain::model::storage::DirectoryCompletion;
72    use harmos_sdk::operations::{Operation, Response};
73
74    impl Operation for super::ListDirectory {
75        type Error = Error;
76
77        #[tracing::instrument(target = "harmos::storage", name = "storage.operation.list_directory", level = "trace", skip_all)]
78        async fn run(self, context: harmos_sdk::Context<'_, Self>) -> Result<Response<DirectoryCompletion>> {
79            let storage = context.resource::<harmos_storage::StorageManager<harmos_storage::ErasedCatalog>>();
80            let output = context.streams();
81
82            let mut reader = storage.list_directory(self.selection.clone()).await?;
83            while let Some(item) = reader.next().await? {
84                let response = Response::from_owner(item.owner());
85                tokio::time::timeout(crate::storage::IO_TIMEOUT, output.send_owned(response))
86                    .await
87                    .map_err(|_| crate::storage::output_timeout())??;
88            }
89            Ok(reader.completion()?.into())
90        }
91
92        fn classify(error: &Error) -> harmos_sdk::operations::FailureKind {
93            crate::storage::classify(error)
94        }
95    }
96}
97
98/* === Public Functions === */
99
100/* === Private Functions === */
101
102/* === Tests === */