1use std::fmt::Display;
2use serde::Deserialize;
3use serde::Serialize;
4use crate::mir::binding::VariableDefinition;
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7pub enum Step {
8 MethodCall(MethodCall),
9 Message(Message),
10 RpcCall(RpcCall),
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
14pub struct MethodCall {
15 pub name: String,
16 pub object: String,
17 pub method: String,
18 pub parameters: Vec<VariableDefinition>,
19 pub return_type: Option<VariableDefinition>,
20}
21
22impl MethodCall {
23 pub fn new(name: String) -> Self {
24 MethodCall {
25 name,
26 ..Default::default()
27 }
28 }
29}
30
31impl Display for MethodCall {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 let return_type_str: String = if let Some(return_type) = &self.return_type {
34 format!("{}:{}", return_type.name, return_type.type_type)
35 } else {
36 "".to_owned()
37 };
38 let source = format!("{}.{}", &self.object, &self.method);
39 let params = &self.parameters.iter().map(|p| format!("{}:{}", p.name, p.type_type)).collect::<Vec<String>>().join(", ");
40
41 if return_type_str.is_empty() {
42 write!(f, "call {} with ({})", source, params)
43 } else {
44 write!(f, "get {} from {} with ({})", return_type_str, source, params)
45 }
46 }
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
50pub struct Message {
51 pub from: String,
52 pub to: String,
53 pub topic: String,
54 pub message: String,
55}
56
57impl Display for Message {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "send {} from {} to {}", self.message, self.from, self.topic)
60 }
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
64pub struct RpcCall {
65 pub from: String,
66 pub to: String,
67 pub arguments: Vec<VariableDefinition>,
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_method_call() {
76 let call = MethodCall {
77 name: "call".to_owned(),
78 object: "object".to_owned(),
79 method: "method".to_owned(),
80 parameters: vec![
81 VariableDefinition {
82 name: "param1".to_owned(),
83 type_type: "type1".to_owned(),
84 initializer: None
85 },
86 VariableDefinition {
87 name: "param2".to_owned(),
88 type_type: "type2".to_owned(),
89 initializer: None
90 },
91 ],
92 return_type: Some(VariableDefinition {
93 name: "return".to_owned(),
94 type_type: "type3".to_owned(),
95 initializer: None
96 }),
97 };
98 let comment = call.to_string();
99 assert_eq!(comment, "get return:type3 from object.method with (param1:type1, param2:type2)");
100 }
101
102 #[test]
103 fn test_method_call_without_return() {
104 let call = MethodCall {
105 name: "call".to_owned(),
106 object: "object".to_owned(),
107 method: "method".to_owned(),
108 parameters: vec![
109 VariableDefinition {
110 name: "param1".to_owned(),
111 type_type: "type1".to_owned(),
112 initializer: None
113 },
114 VariableDefinition {
115 name: "param2".to_owned(),
116 type_type: "type2".to_owned(),
117 initializer: None
118 },
119 ],
120 return_type: None,
121 };
122 let comment = call.to_string();
123 assert_eq!(comment, "call object.method with (param1:type1, param2:type2)");
124 }
125
126 #[test]
127 fn format_message() {
128 let message = Message {
129 from: "object".to_owned(),
130 to: "to".to_owned(),
131 topic: "event:event".to_owned(),
132 message: "content".to_owned(),
133 };
134 let comment = message.to_string();
135 assert_eq!(comment, "send content from object to event:event");
136 }
137}