1use crate::traits::identity::Identity;
2use crate::traits::structural_eq::StructuralEq;
3use core::cell::RefCell;
4use core::prelude::rust_2024::*;
5use core::result::Result;
6
7use super::value::Value;
8use crate::references::mutations::DIFUpdateDataOrMemory;
9use crate::references::observers::TransceiverId;
10use crate::references::reference::{AccessError, Reference};
11use crate::runtime::execution::ExecutionError;
12use crate::serde::deserializer::DatexDeserializer;
13use crate::stdlib::borrow::Cow;
14use crate::stdlib::boxed::Box;
15use crate::stdlib::rc::Rc;
16use crate::stdlib::string::String;
17use crate::traits::apply::Apply;
18use crate::traits::value_eq::ValueEq;
19use crate::types::definition::TypeDefinition;
20use crate::values::core_value::CoreValue;
21use crate::values::core_values::r#type::Type;
22use core::fmt::Display;
23use core::hash::{Hash, Hasher};
24use core::ops::FnOnce;
25use core::ops::{Add, Neg, Sub};
26use serde::Deserialize;
27
28#[derive(Debug, Clone, PartialEq)]
29pub enum ValueError {
30 IsVoid,
31 InvalidOperation,
32 IntegerOverflow,
33 TypeConversionError,
34}
35
36impl Display for ValueError {
37 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38 match self {
39 ValueError::IsVoid => core::write!(f, "Value is void"),
40 ValueError::InvalidOperation => {
41 core::write!(f, "Invalid operation on value")
42 }
43 ValueError::TypeConversionError => {
44 core::write!(f, "Type conversion error")
45 }
46 ValueError::IntegerOverflow => {
47 core::write!(f, "Integer overflow occurred")
48 }
49 }
50 }
51}
52
53#[derive(Clone, Debug, PartialEq, Eq, Hash)]
54pub enum ValueKey<'a> {
55 Text(Cow<'a, str>),
56 Index(i64),
57 Value(Cow<'a, ValueContainer>),
58}
59
60impl<'a> ValueKey<'a> {
61 pub fn with_value_container<R>(
62 &self,
63 callback: impl FnOnce(&ValueContainer) -> R,
64 ) -> R {
65 match self {
66 ValueKey::Value(value_container) => callback(value_container),
67 ValueKey::Text(text) => {
68 let value_container = ValueContainer::new_value(text.as_ref());
69 callback(&value_container)
70 }
71 ValueKey::Index(index) => {
72 let value_container = ValueContainer::new_value(*index);
73 callback(&value_container)
74 }
75 }
76 }
77}
78
79impl<'a> Display for ValueKey<'a> {
80 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 match self {
82 ValueKey::Text(text) => core::write!(f, "{}", text),
83 ValueKey::Index(index) => core::write!(f, "{}", index),
84 ValueKey::Value(value_container) => {
85 core::write!(f, "{}", value_container)
86 }
87 }
88 }
89}
90
91impl<'a> From<&'a String> for ValueKey<'a> {
92 fn from(text: &'a String) -> Self {
93 ValueKey::Text(Cow::from(text))
94 }
95}
96
97impl<'a> From<&'a str> for ValueKey<'a> {
98 fn from(text: &'a str) -> Self {
99 ValueKey::Text(Cow::from(text))
100 }
101}
102
103impl<'a> From<i64> for ValueKey<'a> {
104 fn from(index: i64) -> Self {
105 ValueKey::Index(index)
106 }
107}
108
109impl<'a> From<u32> for ValueKey<'a> {
110 fn from(index: u32) -> Self {
111 ValueKey::Index(index as i64)
112 }
113}
114
115impl<'a> From<i32> for ValueKey<'a> {
116 fn from(index: i32) -> Self {
117 ValueKey::Index(index as i64)
118 }
119}
120
121impl<'a> From<&'a ValueContainer> for ValueKey<'a> {
122 fn from(value_container: &'a ValueContainer) -> Self {
123 ValueKey::Value(Cow::Borrowed(value_container))
124 }
125}
126
127impl<'a> ValueKey<'a> {
128 pub fn try_as_text(&self) -> Option<&str> {
129 if let ValueKey::Text(text) = self {
130 Some(text)
131 } else if let ValueKey::Value(val) = self
132 && let ValueContainer::Value(Value {
133 inner: CoreValue::Text(text),
134 ..
135 }) = val.as_ref()
136 {
137 Some(&text.0)
138 } else {
139 None
140 }
141 }
142
143 pub fn try_as_index(&self) -> Option<i64> {
144 if let ValueKey::Index(index) = self {
145 Some(*index)
146 } else if let ValueKey::Value(value) = self
147 && let ValueContainer::Value(Value {
148 inner: CoreValue::Integer(index),
149 ..
150 }) = value.as_ref()
151 {
152 index.as_i64()
153 } else if let ValueKey::Value(value) = self
154 && let ValueContainer::Value(Value {
155 inner: CoreValue::TypedInteger(index),
156 ..
157 }) = value.as_ref()
158 {
159 index.as_i64()
160 } else {
161 None
162 }
163 }
164}
165
166impl<'a> From<ValueKey<'a>> for ValueContainer {
167 fn from(value_key: ValueKey) -> Self {
168 match value_key {
169 ValueKey::Text(text) => {
170 ValueContainer::new_value(text.into_owned())
171 }
172 ValueKey::Index(index) => ValueContainer::new_value(index),
173 ValueKey::Value(value_container) => value_container.into_owned(),
174 }
175 }
176}
177
178#[derive(Debug)]
179pub enum OwnedValueKey {
180 Text(String),
181 Index(i64),
182 Value(ValueContainer),
183}
184
185impl<'a> From<OwnedValueKey> for ValueKey<'a> {
186 fn from(owned: OwnedValueKey) -> Self {
187 match owned {
188 OwnedValueKey::Text(text) => ValueKey::Text(Cow::Owned(text)),
189 OwnedValueKey::Index(index) => ValueKey::Index(index),
190 OwnedValueKey::Value(value_container) => {
191 ValueKey::Value(Cow::Owned(value_container))
192 }
193 }
194 }
195}
196
197#[derive(Clone, Debug, Eq)]
198pub enum ValueContainer {
199 Value(Value),
200 Reference(Reference),
201}
202
203impl<'a> Deserialize<'a> for ValueContainer {
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: serde::Deserializer<'a>,
207 {
208 let deserializer: &DatexDeserializer = unsafe {
209 &*(&deserializer as *const D as *const DatexDeserializer)
210 };
211
212 Ok(deserializer.value.clone())
213 }
214}
215
216impl Hash for ValueContainer {
217 fn hash<H: Hasher>(&self, state: &mut H) {
218 match self {
219 ValueContainer::Value(value) => value.hash(state),
220 ValueContainer::Reference(pointer) => pointer.hash(state),
221 }
222 }
223}
224
225impl PartialEq for ValueContainer {
229 fn eq(&self, other: &Self) -> bool {
230 match (self, other) {
231 (ValueContainer::Value(a), ValueContainer::Value(b)) => a == b,
232 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
233 a == b
234 }
235 _ => false,
236 }
237 }
238}
239
240impl StructuralEq for ValueContainer {
243 fn structural_eq(&self, other: &Self) -> bool {
244 match (self, other) {
245 (ValueContainer::Value(a), ValueContainer::Value(b)) => {
246 a.structural_eq(b)
247 }
248 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
249 a.structural_eq(b)
250 }
251 (ValueContainer::Value(a), ValueContainer::Reference(b))
252 | (ValueContainer::Reference(b), ValueContainer::Value(a)) => {
253 a.structural_eq(&b.collapse_to_value().borrow())
254 }
255 }
256 }
257}
258
259impl ValueEq for ValueContainer {
262 fn value_eq(&self, other: &Self) -> bool {
263 match (self, other) {
264 (ValueContainer::Value(a), ValueContainer::Value(b)) => {
265 a.value_eq(b)
266 }
267 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
268 a.value_eq(b)
269 }
270 (ValueContainer::Value(a), ValueContainer::Reference(b))
271 | (ValueContainer::Reference(b), ValueContainer::Value(a)) => {
272 a.value_eq(&b.collapse_to_value().borrow())
273 }
274 }
275 }
276}
277
278impl Identity for ValueContainer {
281 fn identical(&self, other: &Self) -> bool {
282 match (self, other) {
283 (ValueContainer::Value(_), ValueContainer::Value(_)) => false,
284 (ValueContainer::Reference(a), ValueContainer::Reference(b)) => {
285 a.identical(b)
286 }
287 _ => false,
288 }
289 }
290}
291
292impl Display for ValueContainer {
293 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
294 match self {
295 ValueContainer::Value(value) => core::write!(f, "{value}"),
296 ValueContainer::Reference(reference) => {
298 core::write!(f, "&({})", reference.collapse_to_value().borrow())
299 }
300 }
301 }
302}
303
304impl ValueContainer {
305 pub fn to_value(&self) -> Rc<RefCell<Value>> {
306 match self {
307 ValueContainer::Value(value) => {
308 Rc::new(RefCell::new(value.clone()))
309 }
310 ValueContainer::Reference(pointer) => pointer.collapse_to_value(),
311 }
312 }
313
314 pub fn is_type(&self) -> bool {
315 match self {
316 ValueContainer::Value(value) => value.is_type(),
317 ValueContainer::Reference(reference) => reference.is_type(),
318 }
319 }
320
321 pub fn actual_value_type(&self) -> TypeDefinition {
323 match self {
324 ValueContainer::Value(value) => value.actual_type().clone(),
325 ValueContainer::Reference(reference) => {
326 reference.actual_type().clone()
327 }
328 }
329 }
330
331 pub fn actual_container_type(&self) -> Type {
333 match self {
334 ValueContainer::Value(value) => {
335 Type::new(*value.actual_type.clone(), None)
336 }
337 ValueContainer::Reference(reference) => {
338 let inner_type =
339 reference.value_container().actual_container_type();
340 Type::new(
341 if inner_type.is_reference_type() {
343 TypeDefinition::Type(Box::new(inner_type))
344 }
345 else {
347 inner_type.type_definition
348 },
349 Some(reference.mutability()),
350 )
351 }
352 }
353 }
354
355 pub fn new_value<T: Into<Value>>(value: T) -> ValueContainer {
356 ValueContainer::Value(value.into())
357 }
358
359 pub fn new_reference<T: Into<Reference>>(value: T) -> ValueContainer {
360 ValueContainer::Reference(value.into())
361 }
362
363 pub fn maybe_reference(&self) -> Option<&Reference> {
365 if let ValueContainer::Reference(reference) = self {
366 Some(reference)
367 } else {
368 None
369 }
370 }
371
372 pub fn with_maybe_reference<F, R>(&self, f: F) -> Option<R>
374 where
375 F: FnOnce(&Reference) -> R,
376 {
377 if let ValueContainer::Reference(reference) = self {
378 Some(f(reference))
379 } else {
380 None
381 }
382 }
383
384 pub fn reference_unchecked(&self) -> &Reference {
386 match self {
387 ValueContainer::Reference(reference) => reference,
388 _ => core::panic!("Cannot convert ValueContainer to Reference"),
389 }
390 }
391
392 pub fn try_get_property<'a>(
394 &self,
395 key: impl Into<ValueKey<'a>>,
396 ) -> Result<ValueContainer, AccessError> {
397 match self {
398 ValueContainer::Value(value) => value.try_get_property(key),
399 ValueContainer::Reference(reference) => {
400 reference.try_get_property(key)
401 }
402 }
403 }
404
405 pub fn try_set_property<'a>(
406 &mut self,
407 source_id: TransceiverId,
408 dif_update_data_or_memory: impl Into<DIFUpdateDataOrMemory<'a>>,
409 key: impl Into<ValueKey<'a>>,
410 val: ValueContainer,
411 ) -> Result<(), AccessError> {
412 match self {
413 ValueContainer::Value(v) => v.try_set_property(key, val),
414 ValueContainer::Reference(r) => r.try_set_property(
415 source_id,
416 dif_update_data_or_memory,
417 key,
418 val,
419 ),
420 }
421 }
422}
423
424impl Apply for ValueContainer {
425 fn apply(
426 &self,
427 args: &[ValueContainer],
428 ) -> Result<Option<ValueContainer>, ExecutionError> {
429 match self {
430 ValueContainer::Value(value) => value.apply(args),
431 ValueContainer::Reference(reference) => reference.apply(args),
432 }
433 }
434
435 fn apply_single(
436 &self,
437 arg: &ValueContainer,
438 ) -> Result<Option<ValueContainer>, ExecutionError> {
439 match self {
440 ValueContainer::Value(value) => value.apply_single(arg),
441 ValueContainer::Reference(reference) => reference.apply_single(arg),
442 }
443 }
444}
445
446impl<T: Into<Value>> From<T> for ValueContainer {
447 fn from(value: T) -> Self {
448 ValueContainer::Value(value.into())
449 }
450}
451
452impl Add<ValueContainer> for ValueContainer {
453 type Output = Result<ValueContainer, ValueError>;
454
455 fn add(self, rhs: ValueContainer) -> Self::Output {
456 match (self, rhs) {
457 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
458 (lhs + rhs).map(ValueContainer::Value)
459 }
460 (
461 ValueContainer::Reference(lhs),
462 ValueContainer::Reference(rhs),
463 ) => {
464 let lhs_value = lhs.collapse_to_value().borrow().clone();
465 let rhs_value = rhs.collapse_to_value().borrow().clone();
466 (lhs_value + rhs_value).map(ValueContainer::Value)
467 }
468 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
469 let rhs_value = rhs.collapse_to_value().borrow().clone();
470 (lhs + rhs_value).map(ValueContainer::Value)
471 }
472 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
473 let lhs_value = lhs.collapse_to_value().borrow().clone();
474 (lhs_value + rhs).map(ValueContainer::Value)
475 }
476 }
477 }
478}
479
480impl Add<&ValueContainer> for &ValueContainer {
481 type Output = Result<ValueContainer, ValueError>;
482
483 fn add(self, rhs: &ValueContainer) -> Self::Output {
484 match (self, rhs) {
485 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
486 (lhs + rhs).map(ValueContainer::Value)
487 }
488 (
489 ValueContainer::Reference(lhs),
490 ValueContainer::Reference(rhs),
491 ) => {
492 let lhs_value = lhs.collapse_to_value().borrow().clone();
493 let rhs_value = rhs.collapse_to_value().borrow().clone();
494 (lhs_value + rhs_value).map(ValueContainer::Value)
495 }
496 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
497 let rhs_value = rhs.collapse_to_value().borrow().clone();
498 (lhs + &rhs_value).map(ValueContainer::Value)
499 }
500 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
501 let lhs_value = lhs.collapse_to_value().borrow().clone();
502 (&lhs_value + rhs).map(ValueContainer::Value)
503 }
504 }
505 }
506}
507
508impl Sub<ValueContainer> for ValueContainer {
509 type Output = Result<ValueContainer, ValueError>;
510
511 fn sub(self, rhs: ValueContainer) -> Self::Output {
512 match (self, rhs) {
513 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
514 (lhs - rhs).map(ValueContainer::Value)
515 }
516 (
517 ValueContainer::Reference(lhs),
518 ValueContainer::Reference(rhs),
519 ) => {
520 let lhs_value = lhs.collapse_to_value().borrow().clone();
521 let rhs_value = rhs.collapse_to_value().borrow().clone();
522 (lhs_value - rhs_value).map(ValueContainer::Value)
523 }
524 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
525 let rhs_value = rhs.collapse_to_value().borrow().clone();
526 (lhs - rhs_value).map(ValueContainer::Value)
527 }
528 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
529 let lhs_value = lhs.collapse_to_value().borrow().clone();
530 (lhs_value - rhs).map(ValueContainer::Value)
531 }
532 }
533 }
534}
535
536impl Sub<&ValueContainer> for &ValueContainer {
537 type Output = Result<ValueContainer, ValueError>;
538
539 fn sub(self, rhs: &ValueContainer) -> Self::Output {
540 match (self, rhs) {
541 (ValueContainer::Value(lhs), ValueContainer::Value(rhs)) => {
542 (lhs - rhs).map(ValueContainer::Value)
543 }
544 (
545 ValueContainer::Reference(lhs),
546 ValueContainer::Reference(rhs),
547 ) => {
548 let lhs_value = lhs.collapse_to_value().borrow().clone();
549 let rhs_value = rhs.collapse_to_value().borrow().clone();
550 (lhs_value - rhs_value).map(ValueContainer::Value)
551 }
552 (ValueContainer::Value(lhs), ValueContainer::Reference(rhs)) => {
553 let rhs_value = rhs.collapse_to_value().borrow().clone();
554 (lhs - &rhs_value).map(ValueContainer::Value)
555 }
556 (ValueContainer::Reference(lhs), ValueContainer::Value(rhs)) => {
557 let lhs_value = lhs.collapse_to_value().borrow().clone();
558 (&lhs_value - rhs).map(ValueContainer::Value)
559 }
560 }
561 }
562}
563
564impl Neg for ValueContainer {
565 type Output = Result<ValueContainer, ValueError>;
566
567 fn neg(self) -> Self::Output {
568 match self {
569 ValueContainer::Value(value) => (-value).map(ValueContainer::Value),
570 ValueContainer::Reference(reference) => {
571 let value = reference.collapse_to_value().borrow().clone(); (-value).map(ValueContainer::Value)
573 }
574 }
575 }
576}