Skip to main content

rib/
call_type.rs

1use crate::{ComponentDependencyKey, DynamicParsedFunctionName, Expr};
2use crate::{FullyQualifiedResourceConstructor, VariableId};
3use std::fmt::Display;
4
5#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
6pub enum CallType {
7    Function {
8        component_info: Option<ComponentDependencyKey>,
9        // as compilation progress the function call is expected to a instance_identifier
10        // and will be always `Some`.
11        instance_identifier: Option<Box<InstanceIdentifier>>,
12        // TODO; a dynamic-parsed-function-name can be replaced by ParsedFunctionName
13        // after the introduction of non-lazy resource constructor.
14        function_name: DynamicParsedFunctionName,
15    },
16    VariantConstructor(String),
17    EnumConstructor(String),
18    InstanceCreation(InstanceCreationType),
19}
20
21// InstanceIdentifier holds the variables that are used to identify a worker or resource instance.
22// Unlike InstanceCreationType, this type can be formed only after the instance is inferred
23#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
24pub enum InstanceIdentifier {
25    WitWorker {
26        variable_id: Option<VariableId>,
27        worker_name: Option<Box<Expr>>,
28    },
29
30    WitResource {
31        variable_id: Option<VariableId>,
32        worker_name: Option<Box<Expr>>,
33        resource_name: String,
34    },
35}
36
37impl InstanceIdentifier {
38    pub fn worker_name_mut(&mut self) -> Option<&mut Box<Expr>> {
39        match self {
40            InstanceIdentifier::WitWorker { worker_name, .. } => worker_name.as_mut(),
41            InstanceIdentifier::WitResource { worker_name, .. } => worker_name.as_mut(),
42        }
43    }
44    pub fn worker_name(&self) -> Option<&Expr> {
45        match self {
46            InstanceIdentifier::WitWorker { worker_name, .. } => worker_name.as_deref(),
47            InstanceIdentifier::WitResource { worker_name, .. } => worker_name.as_deref(),
48        }
49    }
50}
51
52#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
53pub enum InstanceCreationType {
54    // A wit worker instance can be created without another module
55    WitWorker {
56        component_info: Option<ComponentDependencyKey>,
57        worker_name: Option<Box<Expr>>,
58    },
59    // an instance type of the type wit-resource can only be part of
60    // another instance (we call it module), which can be theoretically only be
61    // a worker, but we don't restrict this in types, such that it will easily
62    // handle nested wit resources
63    WitResource {
64        component_info: Option<ComponentDependencyKey>,
65        // this module identifier during resource creation will be always a worker module, but we don't necessarily restrict
66        // i.e, we do allow nested resource construction
67        module: Option<InstanceIdentifier>,
68        resource_name: FullyQualifiedResourceConstructor,
69    },
70}
71
72impl InstanceCreationType {
73    pub fn worker_name(&self) -> Option<Expr> {
74        match self {
75            InstanceCreationType::WitWorker { worker_name, .. } => worker_name.as_deref().cloned(),
76            InstanceCreationType::WitResource { module, .. } => {
77                let r = module.as_ref().and_then(|m| m.worker_name());
78                r.cloned()
79            }
80        }
81    }
82}
83
84impl CallType {
85    pub fn function_name(&self) -> Option<DynamicParsedFunctionName> {
86        match self {
87            CallType::Function { function_name, .. } => Some(function_name.clone()),
88            _ => None,
89        }
90    }
91    pub fn worker_expr(&self) -> Option<&Expr> {
92        match self {
93            CallType::Function {
94                instance_identifier,
95                ..
96            } => {
97                let module = instance_identifier.as_ref()?;
98                module.worker_name()
99            }
100            _ => None,
101        }
102    }
103
104    pub fn function_call(
105        function: DynamicParsedFunctionName,
106        component_info: Option<ComponentDependencyKey>,
107    ) -> CallType {
108        CallType::Function {
109            instance_identifier: None,
110            function_name: function,
111            component_info,
112        }
113    }
114
115    pub fn function_call_with_worker(
116        module: InstanceIdentifier,
117        function: DynamicParsedFunctionName,
118        component_info: Option<ComponentDependencyKey>,
119    ) -> CallType {
120        CallType::Function {
121            instance_identifier: Some(Box::new(module)),
122            function_name: function,
123            component_info,
124        }
125    }
126
127    pub fn is_resource_method(&self) -> bool {
128        match self {
129            CallType::Function { function_name, .. } => function_name
130                .to_parsed_function_name()
131                .function
132                .resource_method_name()
133                .is_some(),
134            _ => false,
135        }
136    }
137}
138
139impl Display for CallType {
140    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141        match self {
142            CallType::Function { function_name, .. } => write!(f, "{function_name}"),
143            CallType::VariantConstructor(name) => write!(f, "{name}"),
144            CallType::EnumConstructor(name) => write!(f, "{name}"),
145            CallType::InstanceCreation(instance_creation_type) => match instance_creation_type {
146                InstanceCreationType::WitWorker { .. } => {
147                    write!(f, "instance")
148                }
149                InstanceCreationType::WitResource { resource_name, .. } => {
150                    write!(f, "{}", resource_name.resource_name)
151                }
152            },
153        }
154    }
155}