1use crate::interpreter::interpreter_stack_value::RibInterpreterStackValue;
16use crate::{
17 EvaluatedFnArgs, EvaluatedFqFn, EvaluatedWorkerName, RibFunctionInvoke, RibInput, VariableId,
18};
19use golem_wasm_rpc::ValueAndType;
20use std::collections::HashMap;
21use std::fmt::Debug;
22use std::sync::Arc;
23
24pub struct InterpreterEnv {
25 pub env: HashMap<EnvironmentKey, RibInterpreterStackValue>,
26 pub call_worker_function_async: Arc<dyn RibFunctionInvoke + Sync + Send>,
27}
28
29impl Debug for InterpreterEnv {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("InterpreterEnv")
32 .field("env", &self.env.iter())
33 .finish()
34 }
35}
36
37impl Default for InterpreterEnv {
38 fn default() -> Self {
39 InterpreterEnv {
40 env: HashMap::new(),
41 call_worker_function_async: Arc::new(internal::NoopRibFunctionInvoke),
42 }
43 }
44}
45
46impl InterpreterEnv {
47 pub async fn invoke_worker_function_async(
48 &self,
49 worker_name: Option<String>,
50 function_name: String,
51 args: Vec<ValueAndType>,
52 ) -> Result<ValueAndType, String> {
53 self.call_worker_function_async
54 .invoke(
55 worker_name.map(EvaluatedWorkerName),
56 EvaluatedFqFn(function_name),
57 EvaluatedFnArgs(args),
58 )
59 .await
60 }
61
62 pub fn from_input(env: &RibInput) -> Self {
63 let env = env
64 .input
65 .clone()
66 .into_iter()
67 .map(|(k, v)| {
68 (
69 EnvironmentKey::from_global(k),
70 RibInterpreterStackValue::Val(v),
71 )
72 })
73 .collect();
74
75 InterpreterEnv {
76 env,
77 call_worker_function_async: Arc::new(internal::NoopRibFunctionInvoke),
78 }
79 }
80
81 pub fn from(
82 input: &RibInput,
83 call_worker_function_async: &Arc<dyn RibFunctionInvoke + Sync + Send>,
84 ) -> Self {
85 let mut env = Self::from_input(input);
86 env.call_worker_function_async = call_worker_function_async.clone();
87 env
88 }
89
90 pub fn insert(&mut self, key: EnvironmentKey, value: RibInterpreterStackValue) {
91 self.env.insert(key, value);
92 }
93
94 pub fn lookup(&self, key: &EnvironmentKey) -> Option<&RibInterpreterStackValue> {
95 self.env.get(key)
96 }
97}
98
99#[derive(Debug, Hash, Eq, PartialEq, Clone)]
100pub struct EnvironmentKey {
101 pub variable_id: VariableId,
102}
103
104impl EnvironmentKey {
105 pub fn from(variable_id: VariableId) -> Self {
106 EnvironmentKey { variable_id }
107 }
108
109 pub fn from_global(key: String) -> Self {
110 EnvironmentKey {
111 variable_id: VariableId::global(key),
112 }
113 }
114}
115
116mod internal {
117 use crate::interpreter::env::RibFunctionInvoke;
118 use crate::{EvaluatedFnArgs, EvaluatedFqFn, EvaluatedWorkerName};
119 use async_trait::async_trait;
120 use golem_wasm_ast::analysis::analysed_type::tuple;
121 use golem_wasm_rpc::{Value, ValueAndType};
122
123 pub(crate) struct NoopRibFunctionInvoke;
124
125 #[async_trait]
126 impl RibFunctionInvoke for NoopRibFunctionInvoke {
127 async fn invoke(
128 &self,
129 _worker_name: Option<EvaluatedWorkerName>,
130 _function_name: EvaluatedFqFn,
131 _args: EvaluatedFnArgs,
132 ) -> Result<ValueAndType, String> {
133 Ok(ValueAndType::new(Value::Tuple(vec![]), tuple(vec![])))
134 }
135 }
136}