selium_kernel/drivers/
singleton.rs1use std::{
4 future::{Future, ready},
5 sync::Arc,
6};
7
8use wasmtime::Caller;
9
10use crate::{
11 guest_data::{GuestError, GuestResult},
12 operation::{Contract, Operation},
13 registry::InstanceRegistry,
14};
15use selium_abi::{GuestResourceId, SingletonLookup, SingletonRegister};
16
17type SingletonOps = (
18 Arc<Operation<SingletonRegisterDriver>>,
19 Arc<Operation<SingletonLookupDriver>>,
20);
21
22pub struct SingletonRegisterDriver;
24pub struct SingletonLookupDriver;
26
27impl Contract for SingletonRegisterDriver {
28 type Input = SingletonRegister;
29 type Output = ();
30
31 fn to_future(
32 &self,
33 caller: &mut Caller<'_, InstanceRegistry>,
34 input: Self::Input,
35 ) -> impl Future<Output = GuestResult<Self::Output>> + 'static {
36 let registry = caller.data().registry_arc();
37 let SingletonRegister { id, resource } = input;
38
39 ready((|| -> GuestResult<Self::Output> {
40 let resource_id = registry
41 .resolve_shared(resource)
42 .ok_or(GuestError::NotFound)?;
43 registry.metadata(resource_id).ok_or(GuestError::NotFound)?;
44 let inserted = registry.register_singleton(id, resource_id)?;
45 if !inserted {
46 return Err(GuestError::StableIdExists);
47 }
48 Ok(())
49 })())
50 }
51}
52
53impl Contract for SingletonLookupDriver {
54 type Input = SingletonLookup;
55 type Output = GuestResourceId;
56
57 fn to_future(
58 &self,
59 caller: &mut Caller<'_, InstanceRegistry>,
60 input: Self::Input,
61 ) -> impl Future<Output = GuestResult<Self::Output>> + 'static {
62 let registry = caller.data().registry_arc();
63 let SingletonLookup { id } = input;
64
65 ready((|| -> GuestResult<Self::Output> {
66 let resource_id = registry.singleton(id).ok_or(GuestError::NotFound)?;
67 registry.metadata(resource_id).ok_or(GuestError::NotFound)?;
68 registry.share_handle(resource_id).map_err(GuestError::from)
69 })())
70 }
71}
72
73pub fn operations() -> SingletonOps {
75 (
76 Operation::from_hostcall(
77 SingletonRegisterDriver,
78 selium_abi::hostcall_contract!(SINGLETON_REGISTER),
79 ),
80 Operation::from_hostcall(
81 SingletonLookupDriver,
82 selium_abi::hostcall_contract!(SINGLETON_LOOKUP),
83 ),
84 )
85}