Skip to main content

harmos_sdk/operations/
surface.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10// The host one authored body uses wherever it runs: in process over
11// the operation manager, in a sidecar over the connection frames, or in a guest
12// over the Wasm imports. Storage and other host services are reached as
13// declared operations through `call` and `submit`, never as per-kit methods.
14
15/* === Modules === */
16
17/* === Re-Exports === */
18
19/* === Imports === */
20
21// Standard Library Imports
22use std::future::Future;
23
24// Third Party Imports
25
26// Local Imports
27use super::instance::Instance;
28use super::{CallContext, ContextError, ContextValue, OperationDeclaration, Response};
29use crate::operations::streams::Publish;
30use crate::{Message, StreamSpec};
31
32/* === Constants === */
33
34/* === Macros === */
35
36/* === Type Aliases === */
37
38/* === Structs === */
39
40/* === Enums === */
41
42/* === Traits === */
43
44// The host one authored body calls through wherever it runs. The request is
45// the operation, so `call` and `submit` infer the declaration from it.
46pub trait Host: Send + Sync + Sized {
47    type Error: std::error::Error + Send + Sync + 'static;
48
49    type Instance<O: OperationDeclaration>: Instance<O, Error = Self::Error>;
50
51    fn context(&self) -> &CallContext;
52
53    fn with_value<T: ContextValue>(&self, value: T) -> Result<Self, ContextError>;
54
55    fn submit<O: OperationDeclaration>(&self, request: O) -> impl Future<Output = Result<Self::Instance<O>, Self::Error>> + Send;
56
57    fn call<O: OperationDeclaration>(&self, request: O) -> impl Future<Output = Result<Response<O::Response>, Self::Error>> + Send;
58
59    // Activate a resident declaration (an observer or a service) over
60    // caller-owned resources. Activations sharing the same resources share one
61    // instance and each handle holds its own lease; releasing the last lease
62    // stops it. Bindings that cannot carry process-local resources refuse.
63    fn submit_with_resources<O: OperationDeclaration<Response = ()>, R: Send + Sync + 'static>(
64        &self, request: O, resources: std::sync::Arc<R>,
65    ) -> impl Future<Output = Result<Self::Instance<O>, Self::Error>> + Send;
66
67    // Publish one row on a declared stream through the host's `host.publish`.
68    fn publish_on<S: StreamSpec>(&self, row: &S::Row) -> impl Future<Output = Result<(), Self::Error>> + Send
69    where
70        S::Row: Message,
71    {
72        let published = self.call(Publish {
73            stream: S::ID.to_owned(),
74            schema: S::VERSION,
75            sequence: None,
76            published_unix_micros: None,
77            context: None,
78            payload: row.encode_to_vec(),
79            following: Vec::new(),
80        });
81        async move {
82            published.await?;
83            Ok(())
84        }
85    }
86
87    fn publish<S: StreamSpec<Row = S> + Message>(&self, row: &S) -> impl Future<Output = Result<(), Self::Error>> + Send {
88        self.publish_on::<S>(row)
89    }
90}
91
92/* === Implementations === */
93
94/* === Public Functions === */
95
96/* === Private Functions === */
97
98/* === Tests === */