1use crate::instance_type::FullyQualifiedResourceConstructor;
16use crate::{DynamicParsedFunctionName, Expr};
17use std::fmt::Display;
18use std::ops::Deref;
19
20#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
21pub enum CallType {
22 Function {
23 worker: Option<Box<Expr>>,
24 function_name: DynamicParsedFunctionName,
25 },
26 VariantConstructor(String),
27 EnumConstructor(String),
28 InstanceCreation(InstanceCreationType),
29}
30
31#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd)]
32pub enum InstanceCreationType {
33 Worker {
34 worker_name: Option<Box<Expr>>,
35 },
36 Resource {
37 worker_name: Option<Box<Expr>>,
38 resource_name: FullyQualifiedResourceConstructor,
39 },
40}
41
42impl InstanceCreationType {
43 pub fn worker_name(&self) -> Option<Expr> {
44 match self {
45 InstanceCreationType::Worker { worker_name, .. } => {
46 worker_name.clone().map(|w| w.deref().clone())
47 }
48 InstanceCreationType::Resource { worker_name, .. } => {
49 worker_name.clone().map(|w| w.deref().clone())
50 }
51 }
52 }
53}
54
55impl CallType {
56 pub fn function_name(&self) -> Option<DynamicParsedFunctionName> {
57 match self {
58 CallType::Function { function_name, .. } => Some(function_name.clone()),
59 _ => None,
60 }
61 }
62 pub fn worker_expr(&self) -> Option<&Expr> {
63 match self {
64 CallType::Function { worker, .. } => worker.as_deref(),
65 _ => None,
66 }
67 }
68
69 pub fn worker_expr_mut(&mut self) -> Option<&mut Box<Expr>> {
70 match self {
71 CallType::Function { worker, .. } => worker.as_mut(),
72 _ => None,
73 }
74 }
75 pub fn function_without_worker(function: DynamicParsedFunctionName) -> CallType {
76 CallType::Function {
77 worker: None,
78 function_name: function,
79 }
80 }
81 pub fn is_resource_method(&self) -> bool {
82 match self {
83 CallType::Function { function_name, .. } => function_name
84 .to_parsed_function_name()
85 .function
86 .resource_method_name()
87 .is_some(),
88 _ => false,
89 }
90 }
91}
92
93impl Display for CallType {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 match self {
96 CallType::Function { function_name, .. } => write!(f, "{}", function_name),
97 CallType::VariantConstructor(name) => write!(f, "{}", name),
98 CallType::EnumConstructor(name) => write!(f, "{}", name),
99 CallType::InstanceCreation(instance_creation_type) => match instance_creation_type {
100 InstanceCreationType::Worker { .. } => {
101 write!(f, "instance")
102 }
103 InstanceCreationType::Resource { resource_name, .. } => {
104 write!(f, "{}", resource_name.resource_name)
105 }
106 },
107 }
108 }
109}
110
111#[cfg(feature = "protobuf")]
112mod protobuf {
113 use crate::call_type::{CallType, InstanceCreationType};
114 use crate::instance_type::FullyQualifiedResourceConstructor;
115 use crate::{DynamicParsedFunctionName, Expr, ParsedFunctionName};
116 use golem_api_grpc::proto::golem::rib::WorkerInstance;
117
118 impl TryFrom<golem_api_grpc::proto::golem::rib::InstanceCreationType> for InstanceCreationType {
119 type Error = String;
120 fn try_from(
121 value: golem_api_grpc::proto::golem::rib::InstanceCreationType,
122 ) -> Result<Self, Self::Error> {
123 match value.kind.ok_or("Missing instance creation kind")? {
124 golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Worker(
125 worker_instance,
126 ) => {
127 let worker_name = worker_instance
128 .worker_name
129 .map(|w| Expr::try_from(*w))
130 .transpose()?
131 .map(Box::new);
132
133 Ok(InstanceCreationType::Worker { worker_name })
134 }
135 golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Resource(
136 resource_instance,
137 ) => {
138 let worker_name = resource_instance
139 .worker_name
140 .map(|w| Expr::try_from(*w))
141 .transpose()?
142 .map(Box::new);
143 let resource_constructor_proto = resource_instance
144 .resource_name
145 .ok_or("Missing resource name")?;
146 let resource_name =
147 FullyQualifiedResourceConstructor::try_from(resource_constructor_proto)?;
148
149 Ok(InstanceCreationType::Resource {
150 worker_name,
151 resource_name,
152 })
153 }
154 }
155 }
156 }
157
158 impl From<InstanceCreationType> for golem_api_grpc::proto::golem::rib::InstanceCreationType {
159 fn from(value: InstanceCreationType) -> Self {
160 match value {
161 InstanceCreationType::Worker { worker_name } => {
162 golem_api_grpc::proto::golem::rib::InstanceCreationType {
163 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Worker(Box::new(WorkerInstance {
164 worker_name: worker_name.clone().map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
165 }))),
166 }
167 }
168 InstanceCreationType::Resource { worker_name, resource_name } => {
169 golem_api_grpc::proto::golem::rib::InstanceCreationType {
170 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Resource(Box::new(golem_api_grpc::proto::golem::rib::ResourceInstanceWithWorkerName {
171 worker_name: worker_name.clone().map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
172 resource_name: Some(golem_api_grpc::proto::golem::rib::FullyQualifiedResourceConstructor::from(resource_name)),
173 }))),
174 }
175 }
176 }
177 }
178 }
179
180 impl TryFrom<golem_api_grpc::proto::golem::rib::CallType> for CallType {
181 type Error = String;
182 fn try_from(
183 value: golem_api_grpc::proto::golem::rib::CallType,
184 ) -> Result<Self, Self::Error> {
185 let invocation = value.name.ok_or("Missing name of invocation")?;
186 let worker = value
187 .worker_name
188 .map(|w| Expr::try_from(*w))
189 .transpose()?
190 .map(Box::new);
191 match invocation {
192 golem_api_grpc::proto::golem::rib::call_type::Name::Parsed(name) => {
193 Ok(CallType::Function {
194 function_name: DynamicParsedFunctionName::try_from(name)?,
195 worker,
196 })
197 }
198 golem_api_grpc::proto::golem::rib::call_type::Name::VariantConstructor(name) => {
199 Ok(CallType::VariantConstructor(name))
200 }
201 golem_api_grpc::proto::golem::rib::call_type::Name::EnumConstructor(name) => {
202 Ok(CallType::EnumConstructor(name))
203 }
204
205 golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(
206 instance_creation,
207 ) => {
208 let instance_creation = InstanceCreationType::try_from(*instance_creation)?;
209 Ok(CallType::InstanceCreation(instance_creation))
210 }
211 }
212 }
213 }
214
215 impl From<CallType> for golem_api_grpc::proto::golem::rib::CallType {
216 fn from(value: CallType) -> Self {
217 match value {
218 CallType::Function {
219 worker,
220 function_name,
221 } => golem_api_grpc::proto::golem::rib::CallType {
222 worker_name: worker.map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
223 name: Some(golem_api_grpc::proto::golem::rib::call_type::Name::Parsed(
224 function_name.into(),
225 )),
226 },
227 CallType::VariantConstructor(name) => golem_api_grpc::proto::golem::rib::CallType {
228 worker_name: None,
229 name: Some(
230 golem_api_grpc::proto::golem::rib::call_type::Name::VariantConstructor(
231 name,
232 ),
233 ),
234 },
235 CallType::EnumConstructor(name) => golem_api_grpc::proto::golem::rib::CallType {
236 worker_name: None,
237 name: Some(
238 golem_api_grpc::proto::golem::rib::call_type::Name::EnumConstructor(name),
239 ),
240 },
241 CallType::InstanceCreation(instance_creation) => {
242 match instance_creation {
243 InstanceCreationType::Worker { worker_name } => {
244 golem_api_grpc::proto::golem::rib::CallType {
245 worker_name: worker_name.clone().map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
246 name: Some(golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(
247 Box::new(golem_api_grpc::proto::golem::rib::InstanceCreationType {
248 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Worker(Box::new(WorkerInstance {
249 worker_name: worker_name.map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
250 }))),
251 })
252 )),
253 }
254 }
255 InstanceCreationType::Resource { worker_name, resource_name } => {
256 golem_api_grpc::proto::golem::rib::CallType {
257 worker_name: worker_name.clone().map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
258 name: Some(golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(
259 Box::new(golem_api_grpc::proto::golem::rib::InstanceCreationType {
260 kind: Some(golem_api_grpc::proto::golem::rib::instance_creation_type::Kind::Resource(Box::new(golem_api_grpc::proto::golem::rib::ResourceInstanceWithWorkerName {
261 worker_name: worker_name.map(|w| Box::new(golem_api_grpc::proto::golem::rib::Expr::from(*w))),
262 resource_name: Some(golem_api_grpc::proto::golem::rib::FullyQualifiedResourceConstructor::from(resource_name)),
263 }))),
264 })
265 )),
266 }
267 }
268 }
269 }
270 }
271 }
272 }
273
274 impl TryFrom<golem_api_grpc::proto::golem::rib::InvocationName> for CallType {
279 type Error = String;
280 fn try_from(
281 value: golem_api_grpc::proto::golem::rib::InvocationName,
282 ) -> Result<Self, Self::Error> {
283 let invocation = value.name.ok_or("Missing name of invocation")?;
284 match invocation {
285 golem_api_grpc::proto::golem::rib::invocation_name::Name::Parsed(name) => {
286 Ok(CallType::Function {
287 worker: None,
288 function_name: DynamicParsedFunctionName::parse(
289 ParsedFunctionName::try_from(name)?.to_string(),
290 )?,
291 })
292 }
293 golem_api_grpc::proto::golem::rib::invocation_name::Name::VariantConstructor(
294 name,
295 ) => Ok(CallType::VariantConstructor(name)),
296 golem_api_grpc::proto::golem::rib::invocation_name::Name::EnumConstructor(name) => {
297 Ok(CallType::EnumConstructor(name))
298 }
299 }
300 }
301 }
302}