1use serde::{Deserialize, Serialize};
16use std::fmt::Display;
17
18#[derive(Hash, Eq, Debug, Clone, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
19pub enum VariableId {
20 Global(String),
21 Local(String, Option<Id>),
22 MatchIdentifier(MatchIdentifier),
23 ListComprehension(ListComprehensionIdentifier),
24 ListReduce(ListAggregationIdentifier),
25}
26
27impl VariableId {
28 pub fn as_instance_variable(&self) -> VariableId {
29 let variable_string = match self {
30 VariableId::Global(name) => name.clone(),
31 VariableId::Local(name, identifier) => {
32 if let Some(id) = identifier {
33 format!("{}-{}", name, id.0)
34 } else {
35 name.clone()
36 }
37 }
38 VariableId::MatchIdentifier(m) => format!("{}-{}", m.name, m.match_arm_index),
39 VariableId::ListComprehension(l) => l.name.clone(),
40 VariableId::ListReduce(r) => r.name.clone(),
41 };
42
43 VariableId::global(format!("__instance_{variable_string}"))
44 }
45 pub fn list_comprehension_identifier(name: impl AsRef<str>) -> VariableId {
46 VariableId::ListComprehension(ListComprehensionIdentifier {
47 name: name.as_ref().to_string(),
48 })
49 }
50
51 pub fn list_reduce_identifier(name: impl AsRef<str>) -> VariableId {
52 VariableId::ListReduce(ListAggregationIdentifier {
53 name: name.as_ref().to_string(),
54 })
55 }
56
57 pub fn match_identifier(name: String, match_arm_index: usize) -> VariableId {
58 VariableId::MatchIdentifier(MatchIdentifier {
59 name,
60 match_arm_index,
61 })
62 }
63
64 pub fn name(&self) -> String {
65 match self {
66 VariableId::Global(name) => name.clone(),
67 VariableId::Local(name, _) => name.clone(),
68 VariableId::MatchIdentifier(m) => m.name.clone(),
69 VariableId::ListComprehension(l) => l.name.clone(),
70 VariableId::ListReduce(r) => r.name.clone(),
71 }
72 }
73
74 pub fn is_global(&self) -> bool {
75 match self {
76 VariableId::Global(_) => true,
77 VariableId::Local(_, _) => false,
78 VariableId::MatchIdentifier(_) => false,
79 VariableId::ListComprehension(_) => false,
80 VariableId::ListReduce(_) => false,
81 }
82 }
83
84 pub fn is_local(&self) -> bool {
85 match self {
86 VariableId::Global(_) => false,
87 VariableId::Local(_, _) => true,
88 VariableId::MatchIdentifier(_) => false,
89 VariableId::ListComprehension(_) => false,
90 VariableId::ListReduce(_) => false,
91 }
92 }
93
94 pub fn is_match_binding(&self) -> bool {
95 match self {
96 VariableId::Global(_) => false,
97 VariableId::Local(_, _) => false,
98 VariableId::MatchIdentifier(_) => true,
99 VariableId::ListComprehension(_) => false,
100 VariableId::ListReduce(_) => false,
101 }
102 }
103
104 pub fn global(variable_name: String) -> VariableId {
107 VariableId::Global(variable_name)
108 }
109
110 pub fn local(variable_name: &str, id: u32) -> VariableId {
111 VariableId::Local(variable_name.to_string(), Some(Id(id)))
112 }
113
114 pub fn local_with_no_id(name: &str) -> VariableId {
118 VariableId::Local(name.to_string(), None)
119 }
120
121 pub fn increment_local_variable_id(&mut self) -> VariableId {
122 match self {
123 VariableId::Global(name) => VariableId::Local(name.clone(), Some(Id(0))),
124 VariableId::Local(name, id) => {
125 let new_id = id.clone().map_or(Some(Id(0)), |x| Some(Id(x.0 + 1)));
126 *id = new_id.clone();
127 VariableId::Local(name.to_string(), new_id)
128 }
129 VariableId::MatchIdentifier(m) => VariableId::MatchIdentifier(m.clone()),
130 VariableId::ListComprehension(l) => VariableId::ListComprehension(l.clone()),
131 VariableId::ListReduce(l) => VariableId::ListReduce(l.clone()),
132 }
133 }
134}
135
136#[derive(Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
137pub struct ListComprehensionIdentifier {
138 pub name: String,
139}
140
141#[derive(Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
142pub struct ListAggregationIdentifier {
143 pub name: String,
144}
145
146#[derive(Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
147pub struct MatchIdentifier {
148 pub name: String,
149 pub match_arm_index: usize, }
151
152impl MatchIdentifier {
153 pub fn new(name: String, match_arm_index: usize) -> MatchIdentifier {
154 MatchIdentifier {
155 name,
156 match_arm_index,
157 }
158 }
159}
160
161impl Display for VariableId {
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163 match self {
164 VariableId::Global(name) => write!(f, "{name}"),
165 VariableId::Local(name, _) => write!(f, "{name}"),
166 VariableId::MatchIdentifier(m) => write!(f, "{}", m.name),
167 VariableId::ListComprehension(l) => write!(f, "{}", l.name),
168 VariableId::ListReduce(r) => write!(f, "{}", r.name),
169 }
170 }
171}
172#[derive(Hash, Eq, Debug, Clone, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
173pub struct Id(pub(crate) u32);