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