1use crate::values::traits::identity::Identity;
2use crate::values::traits::structural_eq::StructuralEq;
3use std::cell::RefCell;
4
5use super::{reference::Reference, value::Value};
6use crate::values::traits::value_eq::ValueEq;
7use std::fmt::Display;
8use std::hash::Hash;
9use std::ops::{Add, Sub};
10use std::rc::Rc;
11use serde::{Deserialize, Serialize};
12use crate::compiler::compile_value;
13use crate::values::serde::deserializer::DatexDeserializer;
14
15#[derive(Debug, Clone, PartialEq)]
16pub enum ValueError {
17 IsVoid,
18 InvalidOperation,
19 IntegerOverflow,
20 TypeConversionError,
21}
22
23impl Display for ValueError {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 match self {
26 ValueError::IsVoid => write!(f, "Value is void"),
27 ValueError::InvalidOperation => {
28 write!(f, "Invalid operation on value")
29 }
30 ValueError::TypeConversionError => {
31 write!(f, "Type conversion error")
32 }
33 ValueError::IntegerOverflow => {
34 write!(f, "Integer overflow occurred")
35 }
36 }
37 }
38}
39
40#[derive(Clone, Debug, Eq)]
41pub enum ValueContainer {
42 Value(Value),
43 Reference(Reference),
44}
45
46impl Serialize for ValueContainer {
47 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
48 where
49 S: serde::Serializer,
50 {
51 serializer.serialize_newtype_struct("value", &compile_value(self).unwrap())
52 }
53}
54
55impl<'a> Deserialize<'a> for ValueContainer {
56 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57 where
58 D: serde::Deserializer<'a>,
59 {
60 let deserializer: &DatexDeserializer = unsafe {
61 &*(&deserializer as *const D as *const DatexDeserializer)
62 };
63
64 Ok(deserializer.value.clone())
65 }
66}
67
68
69impl Hash for ValueContainer {
70 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
71 match self {
72 ValueContainer::Value(value) => value.hash(state),
73 ValueContainer::Reference(pointer) => pointer.hash(state),
74 }
75 }
76}
77
78impl PartialEq for ValueContainer {
82 fn eq(&self, other: &Self) -> bool {
83 match (self, other) {
84 (ValueContainer::Value(a), ValueContainer::Value(b)) => a == b,
85 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
86 a == b
87 }
88 _ => false,
89 }
90 }
91}
92
93impl StructuralEq for ValueContainer {
96 fn structural_eq(&self, other: &Self) -> bool {
97 match (self, other) {
98 (ValueContainer::Value(a), ValueContainer::Value(b)) => {
99 a.structural_eq(b)
100 }
101 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
102 a.structural_eq(b)
103 }
104 (ValueContainer::Value(a), ValueContainer::Reference(b))
105 | (ValueContainer::Reference(b), ValueContainer::Value(a)) => {
106 a.structural_eq(&b.borrow().current_resolved_value().borrow())
107 }
108 }
109 }
110}
111
112impl ValueEq for ValueContainer {
115 fn value_eq(&self, other: &Self) -> bool {
116 match (self, other) {
117 (ValueContainer::Value(a), ValueContainer::Value(b)) => {
118 a.value_eq(b)
119 }
120 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
121 a.value_eq(b)
122 }
123 (ValueContainer::Value(a), ValueContainer::Reference(b))
124 | (ValueContainer::Reference(b), ValueContainer::Value(a)) => {
125 a.value_eq(&b.borrow().current_resolved_value().borrow())
126 }
127 }
128 }
129}
130
131impl Identity for ValueContainer {
134 fn identical(&self, other: &Self) -> bool {
135 match (self, other) {
136 (ValueContainer::Value(_), ValueContainer::Value(_)) => false,
137 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
138 a.identical(b)
139 }
140 _ => false,
141 }
142 }
143}
144
145impl Display for ValueContainer {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147 match self {
148 ValueContainer::Value(value) => write!(f, "{value}"),
149 ValueContainer::Reference(pointer) => {
151 write!(
152 f,
153 "$({})",
154 pointer.borrow().current_resolved_value().borrow()
155 )
156 }
157 }
158 }
159}
160
161impl ValueContainer {
162 pub fn to_value(&self) -> Rc<RefCell<Value>> {
163 match self {
164 ValueContainer::Value(value) => {
165 Rc::new(RefCell::new(value.clone()))
166 }
167 ValueContainer::Reference(pointer) => {
168 let reference = pointer.0.clone();
169
170 reference.borrow().value_container.to_value()
171 }
172 }
173 }
174}
175
176impl<T: Into<Value>> From<T> for ValueContainer {
177 fn from(value: T) -> Self {
178 ValueContainer::Value(value.into())
179 }
180}
181
182impl Add<ValueContainer> for ValueContainer {
183 type Output = Result<ValueContainer, ValueError>;
184
185 fn add(self, rhs: ValueContainer) -> Self::Output {
186 match (self, rhs) {
187 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
188 (lhs + rhs).map(ValueContainer::Value)
189 }
190 (
191 ValueContainer::Reference(lhs),
192 ValueContainer::Reference(rhs),
193 ) => {
194 let lhs_value =
195 lhs.borrow().current_resolved_value().borrow().clone();
196 let rhs_value =
197 rhs.borrow().current_resolved_value().borrow().clone();
198 (lhs_value + rhs_value).map(ValueContainer::Value)
199 }
200 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
201 let rhs_value =
202 rhs.borrow().current_resolved_value().borrow().clone();
203 (lhs + rhs_value).map(ValueContainer::Value)
204 }
205 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
206 let lhs_value =
207 lhs.borrow().current_resolved_value().borrow().clone();
208 (lhs_value + rhs).map(ValueContainer::Value)
209 }
210 }
211 }
212}
213
214impl Add<&ValueContainer> for &ValueContainer {
215 type Output = Result<ValueContainer, ValueError>;
216
217 fn add(self, rhs: &ValueContainer) -> Self::Output {
218 match (self, rhs) {
219 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
220 (lhs + rhs).map(ValueContainer::Value)
221 }
222 (
223 ValueContainer::Reference(lhs),
224 ValueContainer::Reference(rhs),
225 ) => {
226 let lhs_value =
227 lhs.borrow().current_resolved_value().borrow().clone();
228 let rhs_value =
229 rhs.borrow().current_resolved_value().borrow().clone();
230 (lhs_value + rhs_value).map(ValueContainer::Value)
231 }
232 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
233 let rhs_value =
234 rhs.borrow().current_resolved_value().borrow().clone();
235 (lhs + &rhs_value).map(ValueContainer::Value)
236 }
237 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
238 let lhs_value =
239 lhs.borrow().current_resolved_value().borrow().clone();
240 (&lhs_value + rhs).map(ValueContainer::Value)
241 }
242 }
243 }
244}
245
246impl Sub<ValueContainer> for ValueContainer {
247 type Output = Result<ValueContainer, ValueError>;
248
249 fn sub(self, rhs: ValueContainer) -> Self::Output {
250 match (self, rhs) {
251 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
252 (lhs - rhs).map(ValueContainer::Value)
253 }
254 (
255 ValueContainer::Reference(lhs),
256 ValueContainer::Reference(rhs),
257 ) => {
258 let lhs_value =
259 lhs.borrow().current_resolved_value().borrow().clone();
260 let rhs_value =
261 rhs.borrow().current_resolved_value().borrow().clone();
262 (lhs_value - rhs_value).map(ValueContainer::Value)
263 }
264 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
265 let rhs_value =
266 rhs.borrow().current_resolved_value().borrow().clone();
267 (lhs - rhs_value).map(ValueContainer::Value)
268 }
269 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
270 let lhs_value =
271 lhs.borrow().current_resolved_value().borrow().clone();
272 (lhs_value - rhs).map(ValueContainer::Value)
273 }
274 }
275 }
276}
277
278impl Sub<&ValueContainer> for &ValueContainer {
279 type Output = Result<ValueContainer, ValueError>;
280
281 fn sub(self, rhs: &ValueContainer) -> Self::Output {
282 match (self, rhs) {
283 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
284 (lhs - rhs).map(ValueContainer::Value)
285 }
286 (
287 ValueContainer::Reference(lhs),
288 ValueContainer::Reference(rhs),
289 ) => {
290 let lhs_value =
291 lhs.borrow().current_resolved_value().borrow().clone();
292 let rhs_value =
293 rhs.borrow().current_resolved_value().borrow().clone();
294 (lhs_value - rhs_value).map(ValueContainer::Value)
295 }
296 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
297 let rhs_value =
298 rhs.borrow().current_resolved_value().borrow().clone();
299 (lhs - &rhs_value).map(ValueContainer::Value)
300 }
301 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
302 let lhs_value =
303 lhs.borrow().current_resolved_value().borrow().clone();
304 (&lhs_value - rhs).map(ValueContainer::Value)
305 }
306 }
307 }
308}