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