1use bincode::{Decode, Encode};
16use serde::{Deserialize, Serialize};
17use std::fmt::Display;
18
19#[derive(
20 Hash, Eq, Debug, Clone, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Encode, Decode,
21)]
22pub enum VariableId {
23 Global(String),
24 Local(String, Option<Id>),
25 MatchIdentifier(MatchIdentifier),
26 ListComprehension(ListComprehensionIdentifier),
27 ListReduce(ListAggregationIdentifier),
28}
29
30impl VariableId {
31 pub fn list_comprehension_identifier(name: impl AsRef<str>) -> VariableId {
32 VariableId::ListComprehension(ListComprehensionIdentifier {
33 name: name.as_ref().to_string(),
34 })
35 }
36
37 pub fn list_reduce_identifier(name: impl AsRef<str>) -> VariableId {
38 VariableId::ListReduce(ListAggregationIdentifier {
39 name: name.as_ref().to_string(),
40 })
41 }
42
43 pub fn match_identifier(name: String, match_arm_index: usize) -> VariableId {
44 VariableId::MatchIdentifier(MatchIdentifier {
45 name,
46 match_arm_index,
47 })
48 }
49 pub fn name(&self) -> String {
50 match self {
51 VariableId::Global(name) => name.clone(),
52 VariableId::Local(name, _) => name.clone(),
53 VariableId::MatchIdentifier(m) => m.name.clone(),
54 VariableId::ListComprehension(l) => l.name.clone(),
55 VariableId::ListReduce(r) => r.name.clone(),
56 }
57 }
58
59 pub fn is_global(&self) -> bool {
60 match self {
61 VariableId::Global(_) => true,
62 VariableId::Local(_, _) => false,
63 VariableId::MatchIdentifier(_) => false,
64 VariableId::ListComprehension(_) => false,
65 VariableId::ListReduce(_) => false,
66 }
67 }
68
69 pub fn is_local(&self) -> bool {
70 match self {
71 VariableId::Global(_) => false,
72 VariableId::Local(_, _) => true,
73 VariableId::MatchIdentifier(_) => false,
74 VariableId::ListComprehension(_) => false,
75 VariableId::ListReduce(_) => false,
76 }
77 }
78
79 pub fn is_match_binding(&self) -> bool {
80 match self {
81 VariableId::Global(_) => false,
82 VariableId::Local(_, _) => false,
83 VariableId::MatchIdentifier(_) => true,
84 VariableId::ListComprehension(_) => false,
85 VariableId::ListReduce(_) => false,
86 }
87 }
88
89 pub fn global(variable_name: String) -> VariableId {
92 VariableId::Global(variable_name)
93 }
94
95 pub fn local(variable_name: &str, id: u32) -> VariableId {
96 VariableId::Local(variable_name.to_string(), Some(Id(id)))
97 }
98
99 pub fn local_with_no_id(name: &str) -> VariableId {
103 VariableId::Local(name.to_string(), None)
104 }
105
106 pub fn increment_local_variable_id(&mut self) -> VariableId {
107 match self {
108 VariableId::Global(name) => VariableId::Local(name.clone(), Some(Id(0))),
109 VariableId::Local(name, id) => {
110 let new_id = id.clone().map_or(Some(Id(0)), |x| Some(Id(x.0 + 1)));
111 *id = new_id.clone();
112 VariableId::Local(name.to_string(), new_id)
113 }
114 VariableId::MatchIdentifier(m) => VariableId::MatchIdentifier(m.clone()),
115 VariableId::ListComprehension(l) => VariableId::ListComprehension(l.clone()),
116 VariableId::ListReduce(l) => VariableId::ListReduce(l.clone()),
117 }
118 }
119}
120
121#[derive(
122 Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, Ord, PartialOrd,
123)]
124pub struct ListComprehensionIdentifier {
125 pub name: String,
126}
127
128#[derive(
129 Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, Ord, PartialOrd,
130)]
131pub struct ListAggregationIdentifier {
132 pub name: String,
133}
134
135#[derive(
136 Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, Ord, PartialOrd,
137)]
138pub struct MatchIdentifier {
139 pub name: String,
140 pub match_arm_index: usize, }
142
143impl MatchIdentifier {
144 pub fn new(name: String, match_arm_index: usize) -> MatchIdentifier {
145 MatchIdentifier {
146 name,
147 match_arm_index,
148 }
149 }
150}
151
152impl Display for VariableId {
153 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
154 match self {
155 VariableId::Global(name) => write!(f, "{}", name),
156 VariableId::Local(name, _) => write!(f, "{}", name),
157 VariableId::MatchIdentifier(m) => write!(f, "{}", m.name),
158 VariableId::ListComprehension(l) => write!(f, "{}", l.name),
159 VariableId::ListReduce(r) => write!(f, "{}", r.name),
160 }
161 }
162}
163#[derive(
164 Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, Ord, PartialOrd,
165)]
166pub struct Id(pub(crate) u32);
167
168#[cfg(feature = "protobuf")]
169mod protobuf {
170 use crate::{Id, VariableId};
171 use golem_api_grpc::proto::golem::rib::VariableId as ProtoVariableId;
172
173 impl TryFrom<ProtoVariableId> for VariableId {
174 type Error = String;
175
176 fn try_from(value: ProtoVariableId) -> Result<Self, Self::Error> {
177 let variable_id = value.variable_id.ok_or("Missing variable_id".to_string())?;
178
179 match variable_id {
180 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Global(global) => {
181 Ok(VariableId::Global(global.name))
182 }
183 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Local(local) => Ok(
184 VariableId::Local(local.name, local.id.map(|x| Id(x as u32))),
185 ),
186 }
187 }
188 }
189
190 impl From<VariableId> for ProtoVariableId {
191 fn from(value: VariableId) -> Self {
192 match value {
193 VariableId::Global(name) => ProtoVariableId {
194 variable_id: Some(
195 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Global(
196 golem_api_grpc::proto::golem::rib::Global { name },
197 ),
198 ),
199 },
200 VariableId::MatchIdentifier(m) => ProtoVariableId {
201 variable_id: Some(
202 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Global(
203 golem_api_grpc::proto::golem::rib::Global { name: m.name },
204 ),
205 ),
206 },
207 VariableId::Local(name, id) => ProtoVariableId {
208 variable_id: Some(
209 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Local(
210 golem_api_grpc::proto::golem::rib::Local {
211 name,
212 id: id.map(|x| x.0 as u64),
213 },
214 ),
215 ),
216 },
217 VariableId::ListComprehension(l) => ProtoVariableId {
218 variable_id: Some(
219 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Global(
220 golem_api_grpc::proto::golem::rib::Global { name: l.name },
221 ),
222 ),
223 },
224 VariableId::ListReduce(r) => ProtoVariableId {
225 variable_id: Some(
226 golem_api_grpc::proto::golem::rib::variable_id::VariableId::Global(
227 golem_api_grpc::proto::golem::rib::Global { name: r.name },
228 ),
229 ),
230 },
231 }
232 }
233 }
234}