1use crate::{ComponentDependencyKey, DynamicParsedFunctionName, Expr};
16use crate::{FullyQualifiedResourceConstructor, VariableId};
17use std::fmt::Display;
18
19#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
20pub enum CallType {
21 Function {
22 component_info: Option<ComponentDependencyKey>,
23 instance_identifier: Option<Box<InstanceIdentifier>>,
26 function_name: DynamicParsedFunctionName,
29 },
30 VariantConstructor(String),
31 EnumConstructor(String),
32 InstanceCreation(InstanceCreationType),
33}
34
35#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
38pub enum InstanceIdentifier {
39 WitWorker {
40 variable_id: Option<VariableId>,
41 worker_name: Option<Box<Expr>>,
42 },
43
44 WitResource {
45 variable_id: Option<VariableId>,
46 worker_name: Option<Box<Expr>>,
47 resource_name: String,
48 },
49}
50
51impl InstanceIdentifier {
52 pub fn worker_name_mut(&mut self) -> Option<&mut Box<Expr>> {
53 match self {
54 InstanceIdentifier::WitWorker { worker_name, .. } => worker_name.as_mut(),
55 InstanceIdentifier::WitResource { worker_name, .. } => worker_name.as_mut(),
56 }
57 }
58 pub fn worker_name(&self) -> Option<&Expr> {
59 match self {
60 InstanceIdentifier::WitWorker { worker_name, .. } => worker_name.as_deref(),
61 InstanceIdentifier::WitResource { worker_name, .. } => worker_name.as_deref(),
62 }
63 }
64}
65
66#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
67pub enum InstanceCreationType {
68 WitWorker {
70 component_info: Option<ComponentDependencyKey>,
71 worker_name: Option<Box<Expr>>,
72 },
73 WitResource {
78 component_info: Option<ComponentDependencyKey>,
79 module: Option<InstanceIdentifier>,
82 resource_name: FullyQualifiedResourceConstructor,
83 },
84}
85
86impl InstanceCreationType {
87 pub fn worker_name(&self) -> Option<Expr> {
88 match self {
89 InstanceCreationType::WitWorker { worker_name, .. } => worker_name.as_deref().cloned(),
90 InstanceCreationType::WitResource { module, .. } => {
91 let r = module.as_ref().and_then(|m| m.worker_name());
92 r.cloned()
93 }
94 }
95 }
96}
97
98impl CallType {
99 pub fn function_name(&self) -> Option<DynamicParsedFunctionName> {
100 match self {
101 CallType::Function { function_name, .. } => Some(function_name.clone()),
102 _ => None,
103 }
104 }
105 pub fn worker_expr(&self) -> Option<&Expr> {
106 match self {
107 CallType::Function {
108 instance_identifier,
109 ..
110 } => {
111 let module = instance_identifier.as_ref()?;
112 module.worker_name()
113 }
114 _ => None,
115 }
116 }
117
118 pub fn function_call(
119 function: DynamicParsedFunctionName,
120 component_info: Option<ComponentDependencyKey>,
121 ) -> CallType {
122 CallType::Function {
123 instance_identifier: None,
124 function_name: function,
125 component_info,
126 }
127 }
128
129 pub fn function_call_with_worker(
130 module: InstanceIdentifier,
131 function: DynamicParsedFunctionName,
132 component_info: Option<ComponentDependencyKey>,
133 ) -> CallType {
134 CallType::Function {
135 instance_identifier: Some(Box::new(module)),
136 function_name: function,
137 component_info,
138 }
139 }
140
141 pub fn is_resource_method(&self) -> bool {
142 match self {
143 CallType::Function { function_name, .. } => function_name
144 .to_parsed_function_name()
145 .function
146 .resource_method_name()
147 .is_some(),
148 _ => false,
149 }
150 }
151}
152
153impl Display for CallType {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 match self {
156 CallType::Function { function_name, .. } => write!(f, "{function_name}"),
157 CallType::VariantConstructor(name) => write!(f, "{name}"),
158 CallType::EnumConstructor(name) => write!(f, "{name}"),
159 CallType::InstanceCreation(instance_creation_type) => match instance_creation_type {
160 InstanceCreationType::WitWorker { .. } => {
161 write!(f, "instance")
162 }
163 InstanceCreationType::WitResource { resource_name, .. } => {
164 write!(f, "{}", resource_name.resource_name)
165 }
166 },
167 }
168 }
169}
170
171#[cfg(feature = "protobuf")]
172mod protobuf {
173 use crate::call_type::{CallType, InstanceCreationType};
174 use crate::FullyQualifiedResourceConstructor;
175 use crate::{ComponentDependencyKey, DynamicParsedFunctionName, Expr, ParsedFunctionName};
176 use golem_api_grpc::proto::golem::rib::WorkerInstance;
177
178 impl TryFrom<golem_api_grpc::proto::golem::rib::ComponentDependencyKey> for ComponentDependencyKey {
179 type Error = String;
180
181 fn try_from(
182 value: golem_api_grpc::proto::golem::rib::ComponentDependencyKey,
183 ) -> Result<Self, Self::Error> {
184 let component_name = value.component_name;
185 let component_id = value.value.ok_or("Missing component id")?;
186 let component_version = value.component_version;
187
188 let root_package_name = value.root_package_name;
189
190 let root_package_version = value.root_package_version;
191
192 Ok(ComponentDependencyKey {
193 component_name,
194 component_id: component_id.into(),
195 component_version,
196 root_package_name,
197 root_package_version,
198 })
199 }
200 }
201
202 impl From<ComponentDependencyKey> for golem_api_grpc::proto::golem::rib::ComponentDependencyKey {
203 fn from(value: ComponentDependencyKey) -> Self {
204 golem_api_grpc::proto::golem::rib::ComponentDependencyKey {
205 component_name: value.component_name,
206 component_version: value.component_version,
207 value: Some(value.component_id.into()),
208 root_package_name: value.root_package_name,
209 root_package_version: value.root_package_version,
210 }
211 }
212 }
213
214 impl TryFrom<golem_api_grpc::proto::golem::rib::InstanceCreationType> for InstanceCreationType {
215 type Error = String;
216 fn try_from(
217 value: golem_api_grpc::proto::golem::rib::InstanceCreationType,
218 ) -> Result<Self, Self::Error> {
219 match value.kind.ok_or("Missing instance creation kind")? {
220 golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Worker(
221 worker_instance,
222 ) => {
223 let worker_name = worker_instance
224 .worker_name
225 .map(|w| Expr::try_from(*w))
226 .transpose()?
227 .map(Box::new);
228
229 Ok(InstanceCreationType::WitWorker {
230 component_info: None,
231 worker_name,
232 })
233 }
234 golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Resource(
235 resource_instance,
236 ) => {
237 let resource_constructor_proto = resource_instance
238 .resource_name
239 .ok_or("Missing resource name")?;
240 let resource_name =
241 FullyQualifiedResourceConstructor::try_from(resource_constructor_proto)?;
242
243 let component_info = resource_instance
244 .component
245 .map(ComponentDependencyKey::try_from)
246 .transpose()?;
247
248 Ok(InstanceCreationType::WitResource {
249 component_info,
250 module: None,
251 resource_name,
252 })
253 }
254 }
255 }
256 }
257
258 impl From<InstanceCreationType> for golem_api_grpc::proto::golem::rib::InstanceCreationType {
259 fn from(value: InstanceCreationType) -> Self {
260 match value {
261 InstanceCreationType::WitWorker { component_info, .. } => {
262 golem_api_grpc::proto::golem::rib::InstanceCreationType {
263 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Worker(Box::new(WorkerInstance {
264 component: component_info.map(golem_api_grpc::proto::golem::rib::ComponentDependencyKey::from),
265 worker_name: None
266 }))),
267 }
268 }
269 InstanceCreationType::WitResource { component_info, resource_name, .. } => {
270 golem_api_grpc::proto::golem::rib::InstanceCreationType {
271 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Resource(Box::new(golem_api_grpc::proto::golem::rib::ResourceInstanceWithWorkerName {
272 component: component_info.map(golem_api_grpc::proto::golem::rib::ComponentDependencyKey::from),
273 worker_name: None,
274 resource_name: Some(golem_api_grpc::proto::golem::rib::FullyQualifiedResourceConstructor::from(resource_name)),
275 }))),
276 }
277 }
278 }
279 }
280 }
281
282 impl TryFrom<golem_api_grpc::proto::golem::rib::CallType> for CallType {
283 type Error = String;
284 fn try_from(
285 value: golem_api_grpc::proto::golem::rib::CallType,
286 ) -> Result<Self, Self::Error> {
287 let invocation = value.name.ok_or("Missing name of invocation")?;
288 match invocation {
289 golem_api_grpc::proto::golem::rib::call_type::Name::Parsed(name) => {
290 Ok(CallType::Function {
291 component_info: None,
292 function_name: DynamicParsedFunctionName::try_from(name)?,
293 instance_identifier: None,
294 })
295 }
296 golem_api_grpc::proto::golem::rib::call_type::Name::VariantConstructor(name) => {
297 Ok(CallType::VariantConstructor(name))
298 }
299 golem_api_grpc::proto::golem::rib::call_type::Name::EnumConstructor(name) => {
300 Ok(CallType::EnumConstructor(name))
301 }
302
303 golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(
304 instance_creation,
305 ) => {
306 let instance_creation = InstanceCreationType::try_from(*instance_creation)?;
307 Ok(CallType::InstanceCreation(instance_creation))
308 }
309 }
310 }
311 }
312
313 impl From<CallType> for golem_api_grpc::proto::golem::rib::CallType {
314 fn from(value: CallType) -> Self {
315 match value {
316 CallType::Function {
317 function_name,
318 ..
319 } => golem_api_grpc::proto::golem::rib::CallType {
320 name: Some(golem_api_grpc::proto::golem::rib::call_type::Name::Parsed(
321 function_name.into(),
322 )),
323 },
324 CallType::VariantConstructor(name) => golem_api_grpc::proto::golem::rib::CallType {
325 name: Some(
326 golem_api_grpc::proto::golem::rib::call_type::Name::VariantConstructor(
327 name,
328 ),
329 ),
330 },
331 CallType::EnumConstructor(name) => golem_api_grpc::proto::golem::rib::CallType {
332 name: Some(
333 golem_api_grpc::proto::golem::rib::call_type::Name::EnumConstructor(name),
334 ),
335 },
336 CallType::InstanceCreation(instance_creation) => {
337 match instance_creation {
338 InstanceCreationType::WitWorker { worker_name , component_info} => {
339 golem_api_grpc::proto::golem::rib::CallType {
340 name: Some(golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(
341 Box::new(golem_api_grpc::proto::golem::rib::InstanceCreationType {
342 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Worker(Box::new(WorkerInstance {
343 component: component_info.map(golem_api_grpc::proto::golem::rib::ComponentDependencyKey::from),
344 worker_name: worker_name.map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
345 }))),
346 })
347 )),
348 }
349 }
350 InstanceCreationType::WitResource { resource_name, component_info, .. } => {
351 golem_api_grpc::proto::golem::rib::CallType {
352 name: Some(golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(
353 Box::new(golem_api_grpc::proto::golem::rib::InstanceCreationType {
354 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Resource(Box::new(golem_api_grpc::proto::golem::rib::ResourceInstanceWithWorkerName {
355 component: component_info.map(golem_api_grpc::proto::golem::rib::ComponentDependencyKey::from),
356 worker_name: None,
357 resource_name: Some(golem_api_grpc::proto::golem::rib::FullyQualifiedResourceConstructor::from(resource_name)),
358 }))),
359 })
360 )),
361 }
362 }
363 }
364 }
365 }
366 }
367 }
368
369 impl TryFrom<golem_api_grpc::proto::golem::rib::InvocationName> for CallType {
374 type Error = String;
375 fn try_from(
376 value: golem_api_grpc::proto::golem::rib::InvocationName,
377 ) -> Result<Self, Self::Error> {
378 let invocation = value.name.ok_or("Missing name of invocation")?;
379 match invocation {
380 golem_api_grpc::proto::golem::rib::invocation_name::Name::Parsed(name) => {
381 Ok(CallType::Function {
382 component_info: None,
383 instance_identifier: None,
384 function_name: DynamicParsedFunctionName::parse(
385 ParsedFunctionName::try_from(name)?.to_string(),
386 )?,
387 })
388 }
389 golem_api_grpc::proto::golem::rib::invocation_name::Name::VariantConstructor(
390 name,
391 ) => Ok(CallType::VariantConstructor(name)),
392 golem_api_grpc::proto::golem::rib::invocation_name::Name::EnumConstructor(name) => {
393 Ok(CallType::EnumConstructor(name))
394 }
395 }
396 }
397 }
398}