Skip to main content

harmos_sdk/operations/
authored.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
17use std::future::Future;
18use std::sync::Arc;
19
20// Third Party Imports
21
22// Local Imports
23use super::{FailureKind, OperationDeclaration};
24
25/* === Constants === */
26
27/* === Macros === */
28
29/* === Type Aliases === */
30
31/* === Structs === */
32
33/* === Enums === */
34
35/* === Traits === */
36
37pub trait EndpointSet: Send + 'static {
38    fn item_types() -> (Option<std::any::TypeId>, Option<std::any::TypeId>);
39    fn transferred(&self) -> bool {
40        Self::item_types() != (None, None)
41    }
42}
43
44pub trait InputEndpoint: Send + 'static {
45    type Item: Send + 'static;
46    fn transferred(&self) -> bool {
47        true
48    }
49}
50pub trait OutputEndpoint: Send + 'static {
51    type Item: Send + 'static;
52    fn transferred(&self) -> bool {
53        true
54    }
55}
56
57pub trait Operation: Send + Sized + 'static {
58    type Declaration: OperationDeclaration;
59    type Resources: Send + Sync + 'static;
60    type Error: std::error::Error + Send + Sync + 'static;
61    type Context<'a>: Send;
62    type Endpoints: EndpointSet;
63
64    // Construct the operation for one invocation from its resources and the
65    // first attempt's context; stop and cleanup run only after success.
66    fn initialize<'ctx>(
67        resources: Arc<Self::Resources>, context: Self::Context<'ctx>,
68    ) -> impl Future<Output = Result<Self, Self::Error>> + Send;
69
70    fn run<'ctx>(
71        &mut self, context: Self::Context<'ctx>, request: &mut Self::Declaration, endpoints: &mut Self::Endpoints,
72    ) -> impl Future<Output = Result<super::Response<<Self::Declaration as OperationDeclaration>::Response>, Self::Error>> + Send;
73
74    fn stop(&mut self) -> impl Future<Output = Result<(), Self::Error>> + Send {
75        async { Ok(()) }
76    }
77
78    fn cleanup(&mut self) -> impl Future<Output = Result<(), Self::Error>> + Send {
79        async { Ok(()) }
80    }
81
82    fn transferred(&self) -> bool {
83        false
84    }
85
86    fn classify(_error: &Self::Error) -> FailureKind {
87        FailureKind::Permanent
88    }
89}
90
91/* === Implementations === */
92
93impl EndpointSet for () {
94    fn item_types() -> (Option<std::any::TypeId>, Option<std::any::TypeId>) {
95        (None, None)
96    }
97}
98
99impl<I: InputEndpoint, O: OutputEndpoint> EndpointSet for (I, O) {
100    fn transferred(&self) -> bool {
101        self.0.transferred() || self.1.transferred()
102    }
103    fn item_types() -> (Option<std::any::TypeId>, Option<std::any::TypeId>) {
104        (Some(std::any::TypeId::of::<I::Item>()), Some(std::any::TypeId::of::<O::Item>()))
105    }
106}
107
108/* === Public Functions === */
109
110/* === Private Functions === */
111
112/* === Tests === */