1use crate::traits::identity::Identity;
2use crate::traits::structural_eq::StructuralEq;
3use crate::types::type_container::TypeContainer;
4use std::cell::RefCell;
5
6use super::value::Value;
7use crate::compiler::compile_value;
8use crate::runtime::execution::ExecutionError;
9use crate::serde::deserializer::DatexDeserializer;
10use crate::traits::apply::Apply;
11use crate::traits::value_eq::ValueEq;
12use datex_core::references::reference::Reference;
13use serde::{Deserialize, Serialize};
14use std::fmt::Display;
15use std::hash::Hash;
16use std::ops::{Add, Neg, Sub};
17use std::rc::Rc;
18
19#[derive(Debug, Clone, PartialEq)]
20pub enum ValueError {
21 IsVoid,
22 InvalidOperation,
23 IntegerOverflow,
24 TypeConversionError,
25}
26
27impl Display for ValueError {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 match self {
30 ValueError::IsVoid => write!(f, "Value is void"),
31 ValueError::InvalidOperation => {
32 write!(f, "Invalid operation on value")
33 }
34 ValueError::TypeConversionError => {
35 write!(f, "Type conversion error")
36 }
37 ValueError::IntegerOverflow => {
38 write!(f, "Integer overflow occurred")
39 }
40 }
41 }
42}
43
44#[derive(Clone, Debug, Eq)]
45pub enum ValueContainer {
46 Value(Value),
47 Reference(Reference),
48}
49
50impl Serialize for ValueContainer {
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52 where
53 S: serde::Serializer,
54 {
55 serializer.serialize_newtype_struct(
56 "datex::value",
57 &compile_value(self).unwrap(),
58 )
59 }
60}
61
62impl<'a> Deserialize<'a> for ValueContainer {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: serde::Deserializer<'a>,
66 {
67 let deserializer: &DatexDeserializer = unsafe {
68 &*(&deserializer as *const D as *const DatexDeserializer)
69 };
70
71 Ok(deserializer.value.clone())
72 }
73}
74
75impl Hash for ValueContainer {
76 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
77 match self {
78 ValueContainer::Value(value) => value.hash(state),
79 ValueContainer::Reference(pointer) => pointer.hash(state),
80 }
81 }
82}
83
84impl PartialEq for ValueContainer {
88 fn eq(&self, other: &Self) -> bool {
89 match (self, other) {
90 (ValueContainer::Value(a), ValueContainer::Value(b)) => a == b,
91 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
92 a == b
93 }
94 _ => false,
95 }
96 }
97}
98
99impl StructuralEq for ValueContainer {
102 fn structural_eq(&self, other: &Self) -> bool {
103 match (self, other) {
104 (ValueContainer::Value(a), ValueContainer::Value(b)) => {
105 a.structural_eq(b)
106 }
107 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
108 a.structural_eq(b)
109 }
110 (ValueContainer::Value(a), ValueContainer::Reference(b))
111 | (ValueContainer::Reference(b), ValueContainer::Value(a)) => {
112 a.structural_eq(&b.collapse_to_value().borrow())
113 }
114 }
115 }
116}
117
118impl ValueEq for ValueContainer {
121 fn value_eq(&self, other: &Self) -> bool {
122 match (self, other) {
123 (ValueContainer::Value(a), ValueContainer::Value(b)) => {
124 a.value_eq(b)
125 }
126 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
127 a.value_eq(b)
128 }
129 (ValueContainer::Value(a), ValueContainer::Reference(b))
130 | (ValueContainer::Reference(b), ValueContainer::Value(a)) => {
131 a.value_eq(&b.collapse_to_value().borrow())
132 }
133 }
134 }
135}
136
137impl Identity for ValueContainer {
140 fn identical(&self, other: &Self) -> bool {
141 match (self, other) {
142 (ValueContainer::Value(_), ValueContainer::Value(_)) => false,
143 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
144 a.identical(b)
145 }
146 _ => false,
147 }
148 }
149}
150
151impl Display for ValueContainer {
152 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
153 match self {
154 ValueContainer::Value(value) => write!(f, "{value}"),
155 ValueContainer::Reference(reference) => {
157 write!(f, "&({})", reference.collapse_to_value().borrow())
158 }
159 }
160 }
161}
162
163impl ValueContainer {
164 pub fn to_value(&self) -> Rc<RefCell<Value>> {
165 match self {
166 ValueContainer::Value(value) => {
167 Rc::new(RefCell::new(value.clone()))
168 }
169 ValueContainer::Reference(pointer) => pointer.collapse_to_value(),
170 }
171 }
172
173 pub fn is_type(&self) -> bool {
174 match self {
175 ValueContainer::Value(value) => value.is_type(),
176 ValueContainer::Reference(reference) => reference.is_type(),
177 }
178 }
179
180 pub fn allowed_type(&self) -> TypeContainer {
182 match self {
183 ValueContainer::Value(value) => value.actual_type().clone(),
185 ValueContainer::Reference(reference) => {
186 reference.allowed_type().clone()
187 }
188 }
189 }
190
191 pub fn actual_type(&self) -> TypeContainer {
193 match self {
194 ValueContainer::Value(value) => value.actual_type().clone(),
195 ValueContainer::Reference(reference) => {
196 reference.actual_type().clone()
197 }
198 }
199 }
200
201 pub fn new_value<T: Into<Value>>(value: T) -> ValueContainer {
202 ValueContainer::Value(value.into())
203 }
204
205 pub fn new_reference<T: Into<Reference>>(value: T) -> ValueContainer {
206 ValueContainer::Reference(value.into())
207 }
208
209 pub fn maybe_reference(&self) -> Option<&Reference> {
211 if let ValueContainer::Reference(reference) = self {
212 Some(reference)
213 } else {
214 None
215 }
216 }
217
218 pub fn with_maybe_reference<F, R>(&self, f: F) -> Option<R>
220 where
221 F: FnOnce(&Reference) -> R,
222 {
223 if let ValueContainer::Reference(reference) = self {
224 Some(f(reference))
225 } else {
226 None
227 }
228 }
229
230 pub fn reference_unchecked(&self) -> &Reference {
232 match self {
233 ValueContainer::Reference(reference) => reference,
234 _ => panic!("Cannot convert ValueContainer to Reference"),
235 }
236 }
237
238 pub fn upgrade_combined_value_to_reference(self) -> ValueContainer {
241 match &self {
242 ValueContainer::Reference(_) => self,
244 ValueContainer::Value(value) => {
245 if value.is_collection_value() {
246 ValueContainer::new_reference(self)
247 }
248 else {
250 self
251 }
252 }
253 }
254 }
255}
256
257impl Apply for ValueContainer {
258 fn apply(
259 &self,
260 args: &[ValueContainer],
261 ) -> Result<Option<ValueContainer>, ExecutionError> {
262 match self {
263 ValueContainer::Value(value) => todo!("#309 implement apply for Value"),
264 ValueContainer::Reference(reference) => reference.apply(args),
265 }
266 }
267
268 fn apply_single(
269 &self,
270 arg: &ValueContainer,
271 ) -> Result<Option<ValueContainer>, ExecutionError> {
272 match self {
273 ValueContainer::Value(value) => {
274 todo!("#310 implement apply_single for Value")
275 }
276 ValueContainer::Reference(reference) => reference.apply_single(arg),
277 }
278 }
279}
280
281impl<T: Into<Value>> From<T> for ValueContainer {
282 fn from(value: T) -> Self {
283 ValueContainer::Value(value.into())
284 }
285}
286
287impl From<TypeContainer> for ValueContainer {
288 fn from(type_container: TypeContainer) -> Self {
289 match type_container {
290 TypeContainer::Type(type_value) => {
291 ValueContainer::Value(Value::from(type_value))
292 }
293 TypeContainer::TypeReference(type_reference) => {
294 ValueContainer::Reference(Reference::TypeReference(
295 type_reference,
296 ))
297 }
298 }
299 }
300}
301
302impl Add<ValueContainer> for ValueContainer {
303 type Output = Result<ValueContainer, ValueError>;
304
305 fn add(self, rhs: ValueContainer) -> Self::Output {
306 match (self, rhs) {
307 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
308 (lhs + rhs).map(ValueContainer::Value)
309 }
310 (
311 ValueContainer::Reference(lhs),
312 ValueContainer::Reference(rhs),
313 ) => {
314 let lhs_value = lhs.collapse_to_value().borrow().clone();
315 let rhs_value = rhs.collapse_to_value().borrow().clone();
316 (lhs_value + rhs_value).map(ValueContainer::Value)
317 }
318 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
319 let rhs_value = rhs.collapse_to_value().borrow().clone();
320 (lhs + rhs_value).map(ValueContainer::Value)
321 }
322 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
323 let lhs_value = lhs.collapse_to_value().borrow().clone();
324 (lhs_value + rhs).map(ValueContainer::Value)
325 }
326 }
327 }
328}
329
330impl Add<&ValueContainer> for &ValueContainer {
331 type Output = Result<ValueContainer, ValueError>;
332
333 fn add(self, rhs: &ValueContainer) -> Self::Output {
334 match (self, rhs) {
335 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
336 (lhs + rhs).map(ValueContainer::Value)
337 }
338 (
339 ValueContainer::Reference(lhs),
340 ValueContainer::Reference(rhs),
341 ) => {
342 let lhs_value = lhs.collapse_to_value().borrow().clone();
343 let rhs_value = rhs.collapse_to_value().borrow().clone();
344 (lhs_value + rhs_value).map(ValueContainer::Value)
345 }
346 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
347 let rhs_value = rhs.collapse_to_value().borrow().clone();
348 (lhs + &rhs_value).map(ValueContainer::Value)
349 }
350 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
351 let lhs_value = lhs.collapse_to_value().borrow().clone();
352 (&lhs_value + rhs).map(ValueContainer::Value)
353 }
354 }
355 }
356}
357
358impl Sub<ValueContainer> for ValueContainer {
359 type Output = Result<ValueContainer, ValueError>;
360
361 fn sub(self, rhs: ValueContainer) -> Self::Output {
362 match (self, rhs) {
363 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
364 (lhs - rhs).map(ValueContainer::Value)
365 }
366 (
367 ValueContainer::Reference(lhs),
368 ValueContainer::Reference(rhs),
369 ) => {
370 let lhs_value = lhs.collapse_to_value().borrow().clone();
371 let rhs_value = rhs.collapse_to_value().borrow().clone();
372 (lhs_value - rhs_value).map(ValueContainer::Value)
373 }
374 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
375 let rhs_value = rhs.collapse_to_value().borrow().clone();
376 (lhs - rhs_value).map(ValueContainer::Value)
377 }
378 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
379 let lhs_value = lhs.collapse_to_value().borrow().clone();
380 (lhs_value - rhs).map(ValueContainer::Value)
381 }
382 }
383 }
384}
385
386impl Sub<&ValueContainer> for &ValueContainer {
387 type Output = Result<ValueContainer, ValueError>;
388
389 fn sub(self, rhs: &ValueContainer) -> Self::Output {
390 match (self, rhs) {
391 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
392 (lhs - rhs).map(ValueContainer::Value)
393 }
394 (
395 ValueContainer::Reference(lhs),
396 ValueContainer::Reference(rhs),
397 ) => {
398 let lhs_value = lhs.collapse_to_value().borrow().clone();
399 let rhs_value = rhs.collapse_to_value().borrow().clone();
400 (lhs_value - rhs_value).map(ValueContainer::Value)
401 }
402 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
403 let rhs_value = rhs.collapse_to_value().borrow().clone();
404 (lhs - &rhs_value).map(ValueContainer::Value)
405 }
406 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
407 let lhs_value = lhs.collapse_to_value().borrow().clone();
408 (&lhs_value - rhs).map(ValueContainer::Value)
409 }
410 }
411 }
412}
413
414impl Neg for ValueContainer {
415 type Output = Result<ValueContainer, ValueError>;
416
417 fn neg(self) -> Self::Output {
418 match self {
419 ValueContainer::Value(value) => (-value).map(ValueContainer::Value),
420 ValueContainer::Reference(reference) => {
421 let value = reference.collapse_to_value().borrow().clone(); (-value).map(ValueContainer::Value)
423 }
424 }
425 }
426}