wash_runtime/engine/
ctx.rs1use std::{any::Any, collections::HashMap, sync::Arc};
8
9use wasmtime::component::ResourceTable;
10use wasmtime_wasi::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
11use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
12
13use crate::plugin::HostPlugin;
14
15pub struct Ctx {
19 pub id: String,
21 pub component_id: Arc<str>,
23 pub workload_id: Arc<str>,
25 pub table: wasmtime::component::ResourceTable,
27 pub ctx: WasiCtx,
29 pub http: WasiHttpCtx,
31 plugins: HashMap<&'static str, Arc<dyn Any + Send + Sync>>,
35}
36
37impl Ctx {
38 pub fn get_plugin<T: HostPlugin + 'static>(&self, plugin_id: &str) -> Option<Arc<T>> {
40 self.plugins.get(plugin_id)?.clone().downcast().ok()
41 }
42
43 pub fn builder(
45 workload_id: impl Into<Arc<str>>,
46 component_id: impl Into<Arc<str>>,
47 ) -> CtxBuilder {
48 CtxBuilder::new(workload_id, component_id)
49 }
50}
51
52impl std::fmt::Debug for Ctx {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 f.debug_struct("Ctx")
55 .field("id", &self.id)
56 .field("workload_id", &self.workload_id.as_ref())
57 .field("table", &self.table)
58 .finish()
59 }
60}
61
62impl IoView for Ctx {
63 fn table(&mut self) -> &mut ResourceTable {
64 &mut self.table
65 }
66}
67impl WasiView for Ctx {
69 fn ctx(&mut self) -> &mut WasiCtx {
70 &mut self.ctx
71 }
72}
73
74impl WasiHttpView for Ctx {
76 fn ctx(&mut self) -> &mut WasiHttpCtx {
77 &mut self.http
78 }
79}
80
81pub struct CtxBuilder {
83 id: String,
84 workload_id: Arc<str>,
85 component_id: Arc<str>,
86 ctx: Option<WasiCtx>,
87 plugins: HashMap<&'static str, Arc<dyn HostPlugin + Send + Sync>>,
88}
89
90impl CtxBuilder {
91 pub fn new(workload_id: impl Into<Arc<str>>, component_id: impl Into<Arc<str>>) -> Self {
92 Self {
93 id: uuid::Uuid::new_v4().to_string(),
94 component_id: component_id.into(),
95 workload_id: workload_id.into(),
96 ctx: None,
97 plugins: HashMap::new(),
98 }
99 }
100
101 pub fn with_wasi_ctx(mut self, ctx: WasiCtx) -> Self {
102 self.ctx = Some(ctx);
103 self
104 }
105
106 pub fn with_plugins(
107 mut self,
108 plugins: HashMap<&'static str, Arc<dyn HostPlugin + Send + Sync>>,
109 ) -> Self {
110 self.plugins.extend(plugins);
111 self
112 }
113
114 pub fn build(self) -> Ctx {
115 let plugins = self
116 .plugins
117 .into_iter()
118 .map(|(k, v)| (k, v as Arc<dyn Any + Send + Sync>))
119 .collect();
120
121 Ctx {
122 id: self.id,
123 ctx: self.ctx.unwrap_or_else(|| {
124 WasiCtxBuilder::new()
125 .args(&["main.wasm"])
126 .inherit_stderr()
127 .build()
128 }),
129 workload_id: self.workload_id,
130 component_id: self.component_id,
131 http: WasiHttpCtx::new(),
132 table: ResourceTable::new(),
133 plugins,
134 }
135 }
136}