harmos_sdk/operations/
authored.rs1use std::future::Future;
18
19use super::{ExecutionContext, FailureKind, OperationDeclaration};
23
24pub 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#[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
107pub trait Executable: OperationDeclaration {
109 type Carrier: Carrier<Declaration = Self>;
110
111 const RESOURCES: &'static [super::Resource] = &[];
113}
114
115impl 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