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