waxosuit_guest/lib.rs
1// Copyright 2015-2019 Capital One Services, LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! # waxosuit-guest
16//!
17//! The `waxosuit-guest` library provides WebAssembly module developers with access to the
18//! Waxosuit host runtime. Each guest module has a single call handler, declared with the
19//! `call_handler!` macro. Inside this call handler, the guest
20//! module should check the operation of the delivered message and handle it accordingly,
21//! returning any binary payload in response. It is the responsibility of the guest module to ensure
22//! that the capability provider will be able to understand whichever messages it sends.
23//!
24//! # Example
25//! ```
26//! extern crate waxosuit_guest as guest;
27//!
28//! use guest::prelude::*;
29//!
30//! call_handler!(handle_call);
31//!
32//! pub fn handle_call(ctx: &CapabilitiesContext, operation: &str, msg: &[u8]) -> CallResult {
33//! match operation {
34//! http::OP_HANDLE_REQUEST => hello_world(ctx, msg),
35//! core::OP_HEALTH_REQUEST => Ok(vec![]),
36//! _ => Err("bad dispatch".into()),
37//! }
38//! }
39//!
40//! fn hello_world(
41//! _ctx: &CapabilitiesContext,
42//! _msg: &[u8]) -> CallResult {
43//! Ok(vec![])
44//! }
45//! ```
46
47pub extern crate prost;
48pub extern crate wapc_guest as wapc;
49use crate::kv::KeyValueStore;
50use crate::msg::MessageBroker;
51use crate::raw::RawCapability;
52use wapc::prelude::*;
53use wapc_guest::console_log;
54
55/// Utility function to easily convert a prost Message into a byte vector
56pub fn protobytes(msg: impl prost::Message) -> Result<Vec<u8>> {
57 let mut buf = Vec::new();
58 msg.encode(&mut buf)?;
59 Ok(buf)
60}
61
62#[macro_export]
63macro_rules! call_handler {
64 ($user_handler:ident) => {
65 use $crate::wapc::prelude::*;
66
67 wapc_handler!(handle_wapc);
68 fn handle_wapc(operation: &str, msg: &[u8]) -> CallResult {
69 let ctx = $crate::CapabilitiesContext::new();
70 $user_handler(&ctx, &operation, msg)
71 }
72 };
73}
74
75/// The capabilities context is the gateway through which all guest modules communicate with a host runtime. A reference
76/// to a capabilities context is passed to the call handler defined by the guest module. Individual capabilities are separated
77/// through function calls for each capability provider, including any bound opaque `raw` providers.
78pub struct CapabilitiesContext {
79 kv: KeyValueStore,
80 msg: MessageBroker,
81 raw: RawCapability,
82}
83
84impl Default for CapabilitiesContext {
85 fn default() -> CapabilitiesContext {
86 CapabilitiesContext {
87 kv: KeyValueStore::new(),
88 msg: MessageBroker::new(),
89 raw: RawCapability::new(),
90 }
91 }
92}
93
94impl CapabilitiesContext {
95 pub fn new() -> CapabilitiesContext {
96 Self::default()
97 }
98
99 pub fn kv(&self) -> &KeyValueStore {
100 &self.kv
101 }
102
103 pub fn msg(&self) -> &MessageBroker {
104 &self.msg
105 }
106
107 pub fn raw(&self) -> &RawCapability {
108 &self.raw
109 }
110
111 pub fn log(&self, msg: &str) {
112 console_log(msg);
113 }
114}
115
116pub mod kv;
117pub mod msg;
118pub mod prelude;
119pub mod raw;