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