wapc/wapchost/
modulestate_async.rs1use log::info;
2use tokio::sync::RwLock;
3
4use crate::{HostCallbackAsync, Invocation};
5
6#[derive(Default)]
7pub struct ModuleStateAsync {
13 pub(crate) guest_request: RwLock<Option<Invocation>>,
14 pub(crate) guest_response: RwLock<Option<Vec<u8>>>,
15 pub(crate) host_response: RwLock<Option<Vec<u8>>>,
16 pub(crate) guest_error: RwLock<Option<String>>,
17 pub(crate) host_error: RwLock<Option<String>>,
18 pub(crate) host_callback: Option<Box<HostCallbackAsync>>,
19 pub(crate) id: u64,
20}
21
22impl ModuleStateAsync {
23 pub(crate) fn new(host_callback: Option<Box<HostCallbackAsync>>, id: u64) -> ModuleStateAsync {
24 ModuleStateAsync {
25 host_callback,
26 id,
27 guest_request: RwLock::new(None),
28 guest_response: RwLock::new(None),
29 host_response: RwLock::new(None),
30 guest_error: RwLock::new(None),
31 host_error: RwLock::new(None),
32 }
33 }
34}
35
36impl ModuleStateAsync {
37 pub async fn get_guest_request(&self) -> Option<Invocation> {
39 self.guest_request.read().await.clone()
40 }
41
42 pub async fn get_host_response(&self) -> Option<Vec<u8>> {
44 self.host_response.read().await.clone()
45 }
46
47 pub async fn set_guest_error(&self, error: String) {
49 *self.guest_error.write().await = Some(error);
50 }
51
52 pub async fn set_guest_response(&self, response: Vec<u8>) {
54 *self.guest_response.write().await = Some(response);
55 }
56
57 pub async fn get_guest_response(&self) -> Option<Vec<u8>> {
59 self.guest_response.read().await.clone()
60 }
61
62 pub async fn get_host_error(&self) -> Option<String> {
64 self.host_error.read().await.clone()
65 }
66
67 pub async fn do_host_call(
69 &self,
70 binding: String,
71 namespace: String,
72 operation: String,
73 payload: Vec<u8>,
74 ) -> Result<i32, Box<dyn std::error::Error>> {
75 let id = {
76 *self.host_response.write().await = None;
77 *self.host_error.write().await = None;
78 self.id
79 };
80 let result = match self.host_callback.as_ref() {
81 None => Err("Missing host callback function!".into()),
82 Some(f) => f(id, binding, namespace, operation, payload).await,
83 };
84 Ok(match result {
85 Ok(v) => {
86 *self.host_response.write().await = Some(v);
87 1
88 }
89 Err(e) => {
90 *self.host_error.write().await = Some(format!("{}", e));
91 0
92 }
93 })
94 }
95
96 pub fn do_console_log(&self, msg: &str) {
98 info!("Guest module {}: {}", self.id, msg);
99 }
100}
101
102impl std::fmt::Debug for ModuleStateAsync {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 f.debug_struct("ModuleState")
105 .field("guest_request", &self.guest_request)
106 .field("guest_response", &self.guest_response)
107 .field("host_response", &self.host_response)
108 .field("guest_error", &self.guest_error)
109 .field("host_error", &self.host_error)
110 .field("host_callback", &self.host_callback.as_ref().map(|_| Some("Some(Fn)")))
111 .field("id", &self.id)
112 .finish()
113 }
114}