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::{any::Any, future::Future, sync::Arc};
23
24// Third Party Imports
25
26// Local Imports
27use super::instance::Instance;
28use super::{CallContext, ContextError, ContextValue, OperationDeclaration, Response};
29use crate::{Message, StreamSpec};
30
31/* === Constants === */
32
33/* === Macros === */
34
35/* === Type Aliases === */
36
37/* === Structs === */
38
39// Native Ownership Is Never Part Of A Serialized Operation Declaration.
40#[derive(Clone)]
41pub struct RequestClaims {
42    owner: Arc<dyn Any + Send + Sync>,
43}
44
45/* === Enums === */
46
47/* === Traits === */
48
49// The Carrier Host Preserves Authorization For Child Calls.
50pub trait Host: Send + Sync + Sized {
51    type Error: std::error::Error + Send + Sync + 'static;
52
53    type Instance<O: OperationDeclaration>: Instance<O, Error = Self::Error>;
54
55    fn context(&self) -> &CallContext;
56
57    fn with_value<T: ContextValue>(&self, value: T) -> Result<Self, ContextError>;
58
59    fn submit<O: OperationDeclaration>(&self, request: O::Request) -> impl Future<Output = Result<Self::Instance<O>, Self::Error>> + Send;
60
61    // The caller admits the owner before allocating the request payload. Native
62    // hosts retain it with accepted work; remote hosts refuse local ownership.
63    fn submit_owned<O: OperationDeclaration>(
64        &self, request: O::Request, claims: RequestClaims,
65    ) -> impl Future<Output = Result<Self::Instance<O>, Self::Error>> + Send;
66
67    fn call_owned<O: OperationDeclaration>(
68        &self, request: O::Request, claims: RequestClaims,
69    ) -> impl Future<Output = Result<Response<O::Response>, Self::Error>> + Send {
70        async move { self.submit_owned::<O>(request, claims).await?.join().await }
71    }
72
73    fn call<O: OperationDeclaration>(&self, request: O::Request)
74    -> impl Future<Output = Result<Response<O::Response>, Self::Error>> + Send;
75
76    // Publish one row on a declared stream through the host's `host.publish`.
77    fn publish_on<S: StreamSpec>(&self, row: &S::Row) -> impl Future<Output = Result<(), Self::Error>> + Send
78    where
79        S::Row: Message;
80
81    fn publish<S: StreamSpec<Row = S> + Message>(&self, row: &S) -> impl Future<Output = Result<(), Self::Error>> + Send {
82        self.publish_on::<S>(row)
83    }
84}
85
86/* === Implementations === */
87
88impl RequestClaims {
89    pub fn retain(owner: Arc<dyn Any + Send + Sync>) -> Self {
90        Self { owner }
91    }
92
93    pub fn owner<T: Any + Send + Sync>(&self) -> Option<&T> {
94        self.owner.downcast_ref()
95    }
96}
97
98/* === Public Functions === */
99
100/* === Private Functions === */
101
102/* === Tests === */