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;