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;
18
19// Third Party Imports
20
21// Local Imports
22use super::{ExecutionContext, FailureKind, OperationDeclaration};
23
24/* === Constants === */
25
26/* === Macros === */
27
28/* === Type Aliases === */
29
30/* === Structs === */
31
32/* === Enums === */
33
34/* === Traits === */
35
36pub trait EndpointSet: Send + Sized + 'static {
37    fn empty() -> Option<Self> {
38        None
39    }
40
41    #[cfg(feature = "streaming")]
42    fn bind_wire(_limits: super::WireStreamLimits) -> Result<(Self, super::WireStreams), super::ServingError> {
43        Err(super::ServingError::StreamUnsupported)
44    }
45
46    fn item_types() -> (Option<std::any::TypeId>, Option<std::any::TypeId>);
47    fn transferred(&self) -> bool {
48        Self::item_types() != (None, None)
49    }
50}
51
52pub trait InputEndpoint: Send + Sized + 'static {
53    #[cfg(feature = "streaming")]
54    fn bind_wire(_limits: super::WireStreamLimits) -> Result<(Self, super::WireStreams), super::ServingError> {
55        Err(super::ServingError::StreamUnsupported)
56    }
57
58    type Item: Send + 'static;
59    fn transferred(&self) -> bool {
60        true
61    }
62}
63pub trait OutputEndpoint: Send + Sized + 'static {
64    #[cfg(feature = "streaming")]
65    fn bind_wire(_limits: super::WireStreamLimits) -> Result<(Self, super::WireStreams), super::ServingError> {
66        Err(super::ServingError::StreamUnsupported)
67    }
68
69    type Item: Send + 'static;
70    fn transferred(&self) -> bool {
71        true
72    }
73}
74
75// The Instance Contract Behind Every Registered Operation: Carrier Proxies,
76// Lifecycle Built-Ins And Authored Operations Through `Authored`.
77#[doc(hidden)]
78pub trait Carrier: Send + Sized + 'static {
79    type Declaration: OperationDeclaration;
80    type Error: std::error::Error + Send + Sync + 'static;
81    type StreamEndpoints: EndpointSet;
82
83    fn bind(context: ExecutionContext) -> impl Future<Output = Result<Self, Self::Error>> + Send;
84
85    fn attempt(
86        &mut self, context: ExecutionContext, request: &mut <Self::Declaration as OperationDeclaration>::Request,
87        endpoints: &mut Self::StreamEndpoints,
88    ) -> impl Future<Output = Result<super::Response<<Self::Declaration as OperationDeclaration>::Response>, Self::Error>> + Send;
89
90    fn stop(&mut self) -> impl Future<Output = Result<(), Self::Error>> + Send {
91        async { Ok(()) }
92    }
93
94    fn cleanup(&mut self) -> impl Future<Output = Result<(), Self::Error>> + Send {
95        async { Ok(()) }
96    }
97
98    fn transferred(&self) -> bool {
99        false
100    }
101
102    fn classify(_error: &Self::Error) -> FailureKind {
103        FailureKind::Permanent
104    }
105}
106
107// Selects The Carrier That Executes A Declaration.
108pub trait Executable: OperationDeclaration {
109    type Carrier: Carrier<Declaration = Self>;
110
111    // Registration Verifies The Carrier Resources.
112    const RESOURCES: &'static [super::Resource] = &[];
113}
114
115/* === Implementations === */
116
117impl EndpointSet for () {
118    fn empty() -> Option<Self> {
119        Some(())
120    }
121    fn item_types() -> (Option<std::any::TypeId>, Option<std::any::TypeId>) {
122        (None, None)
123    }
124}
125
126impl<I: InputEndpoint, O: OutputEndpoint> EndpointSet for (I, O) {
127    #[cfg(feature = "streaming")]
128    fn bind_wire(limits: super::WireStreamLimits) -> Result<(Self, super::WireStreams), super::ServingError> {
129        let (input, incoming) = I::bind_wire(limits)?;
130        let (output, outgoing) = O::bind_wire(limits)?;
131        Ok(((input, output), incoming.combine(outgoing)))
132    }
133
134    fn transferred(&self) -> bool {
135        self.0.transferred() || self.1.transferred()
136    }
137    fn item_types() -> (Option<std::any::TypeId>, Option<std::any::TypeId>) {
138        (Some(std::any::TypeId::of::<I::Item>()), Some(std::any::TypeId::of::<O::Item>()))
139    }
140}
141
142/* === Public Functions === */
143
144/* === Private Functions === */
145
146/* === Tests === */