datex_core/references/
value_reference.rs

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