datex_core/references/
value_reference.rs

1use crate::references::observers::Observer;
2use crate::references::reference::ReferenceMutability;
3use crate::stdlib::rc::Rc;
4use crate::traits::value_eq::ValueEq;
5use crate::types::definition::TypeDefinition;
6use crate::utils::freemap::FreeHashMap;
7use crate::values::pointer::PointerAddress;
8use crate::values::value::Value;
9use crate::values::value_container::ValueContainer;
10use core::cell::RefCell;
11use core::fmt::Debug;
12use core::prelude::rust_2024::*;
13
14pub struct ValueReference {
15    /// the value that this reference points to
16    pub value_container: ValueContainer,
17    /// pointer id, can be initialized as None for local pointers
18    pub pointer_address: Option<PointerAddress>,
19    /// custom type for the pointer that the Datex value is allowed to reference
20    pub allowed_type: TypeDefinition,
21    /// list of observer callbacks
22    pub observers: FreeHashMap<u32, Observer>,
23    pub mutability: ReferenceMutability,
24}
25
26impl Default for ValueReference {
27    fn default() -> Self {
28        ValueReference {
29            value_container: ValueContainer::Value(Value::null()),
30            pointer_address: None,
31            allowed_type: TypeDefinition::Unknown,
32            observers: FreeHashMap::new(),
33            mutability: ReferenceMutability::Immutable,
34        }
35    }
36}
37
38impl ValueReference {
39    pub fn new(
40        value_container: ValueContainer,
41        pointer_address: Option<PointerAddress>,
42        allowed_type: TypeDefinition,
43        mutability: ReferenceMutability,
44    ) -> Self {
45        ValueReference {
46            value_container,
47            pointer_address,
48            allowed_type,
49            observers: FreeHashMap::new(),
50            mutability,
51        }
52    }
53}
54
55impl Debug for ValueReference {
56    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57        f.debug_struct("ReferenceData")
58            .field("value_container", &self.value_container)
59            .field("pointer", &self.pointer_address)
60            .field("allowed_type", &self.allowed_type)
61            .field("observers", &self.observers.len())
62            .finish()
63    }
64}
65
66impl PartialEq for ValueReference {
67    fn eq(&self, other: &Self) -> bool {
68        // Two value references are equal if their value containers are equal
69        self.value_container.value_eq(&other.value_container)
70    }
71}
72
73impl ValueReference {
74    pub fn pointer_address(&self) -> &Option<PointerAddress> {
75        &self.pointer_address
76    }
77
78    pub fn current_value_container(&self) -> &ValueContainer {
79        &self.value_container
80    }
81
82    pub fn resolve_current_value(&self) -> Rc<RefCell<Value>> {
83        self.value_container.to_value()
84    }
85
86    pub fn is_mutable(&self) -> bool {
87        core::matches!(self.mutability, ReferenceMutability::Mutable)
88    }
89}