datex_core/dif/
interface.rs

1use crate::dif::r#type::DIFTypeContainer;
2use crate::dif::update::DIFUpdateData;
3use crate::dif::value::DIFValueContainer;
4use crate::references::observers::{
5    ObserveOptions, ObserverError, TransceiverId,
6};
7use crate::references::reference::{
8    AccessError, AssignmentError, ReferenceCreationError, ReferenceMutability,
9    TypeError,
10};
11use crate::runtime::execution::ExecutionError;
12use crate::values::pointer::PointerAddress;
13use datex_core::dif::reference::DIFReference;
14use datex_core::dif::update::DIFUpdate;
15use datex_core::dif::value::DIFReferenceNotFoundError;
16use std::fmt::Display;
17
18#[derive(Debug)]
19pub enum DIFObserveError {
20    ReferenceNotFound,
21    ObserveError(ObserverError),
22}
23impl From<ObserverError> for DIFObserveError {
24    fn from(err: ObserverError) -> Self {
25        DIFObserveError::ObserveError(err)
26    }
27}
28impl Display for DIFObserveError {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        match self {
31            DIFObserveError::ReferenceNotFound => {
32                write!(f, "Reference not found")
33            }
34            DIFObserveError::ObserveError(e) => {
35                write!(f, "Observe error: {}", e)
36            }
37        }
38    }
39}
40
41#[derive(Debug)]
42pub enum DIFUpdateError {
43    ReferenceNotFound,
44    InvalidUpdate,
45    AccessError(AccessError),
46    AssignmentError(AssignmentError),
47    TypeError(Box<TypeError>),
48}
49
50impl From<DIFReferenceNotFoundError> for DIFUpdateError {
51    fn from(_: DIFReferenceNotFoundError) -> Self {
52        DIFUpdateError::ReferenceNotFound
53    }
54}
55impl From<AccessError> for DIFUpdateError {
56    fn from(err: AccessError) -> Self {
57        DIFUpdateError::AccessError(err)
58    }
59}
60impl From<AssignmentError> for DIFUpdateError {
61    fn from(err: AssignmentError) -> Self {
62        DIFUpdateError::AssignmentError(err)
63    }
64}
65impl From<TypeError> for DIFUpdateError {
66    fn from(err: TypeError) -> Self {
67        DIFUpdateError::TypeError(Box::new(err))
68    }
69}
70
71impl Display for DIFUpdateError {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        match self {
74            DIFUpdateError::ReferenceNotFound => {
75                write!(f, "Reference not found")
76            }
77            DIFUpdateError::InvalidUpdate => {
78                write!(f, "Invalid update operation")
79            }
80            DIFUpdateError::AccessError(e) => write!(f, "Access error: {}", e),
81            DIFUpdateError::AssignmentError(e) => {
82                write!(f, "Assignment error: {}", e)
83            }
84            DIFUpdateError::TypeError(e) => write!(f, "Type error: {}", e),
85        }
86    }
87}
88
89#[derive(Debug)]
90pub enum DIFApplyError {
91    ExecutionError(ExecutionError),
92    ReferenceNotFound,
93}
94impl Display for DIFApplyError {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        match self {
97            DIFApplyError::ExecutionError(e) => {
98                write!(f, "Execution error: {}", e)
99            }
100            DIFApplyError::ReferenceNotFound => {
101                write!(f, "Reference not found")
102            }
103        }
104    }
105}
106
107#[derive(Debug)]
108pub enum DIFCreatePointerError {
109    ReferenceNotFound,
110    ReferenceCreationError(ReferenceCreationError),
111}
112
113impl From<DIFReferenceNotFoundError> for DIFCreatePointerError {
114    fn from(_: DIFReferenceNotFoundError) -> Self {
115        DIFCreatePointerError::ReferenceNotFound
116    }
117}
118
119impl Display for DIFCreatePointerError {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        match self {
122            DIFCreatePointerError::ReferenceNotFound => {
123                write!(f, "Reference not found")
124            }
125            DIFCreatePointerError::ReferenceCreationError(e) => {
126                write!(f, "Reference from value container error: {}", e)
127            }
128        }
129    }
130}
131
132#[derive(Debug)]
133pub enum DIFResolveReferenceError {
134    ReferenceNotFound,
135}
136impl Display for DIFResolveReferenceError {
137    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138        match self {
139            DIFResolveReferenceError::ReferenceNotFound => {
140                write!(f, "Reference not found")
141            }
142        }
143    }
144}
145
146impl From<ReferenceCreationError> for DIFCreatePointerError {
147    fn from(err: ReferenceCreationError) -> Self {
148        DIFCreatePointerError::ReferenceCreationError(err)
149    }
150}
151
152pub trait DIFInterface {
153    /// Applies a DIF update to the value at the given pointer address.
154    fn update(
155        &self,
156        source_id: TransceiverId,
157        address: PointerAddress,
158        update: DIFUpdateData,
159    ) -> Result<(), DIFUpdateError>;
160
161    /// Executes an apply operation, applying the `value` to the `callee`.
162    fn apply(
163        &self,
164        callee: DIFValueContainer,
165        value: DIFValueContainer,
166    ) -> Result<DIFValueContainer, DIFApplyError>;
167
168    /// Creates a new pointer and stores it in memory.
169    /// Returns the address of the newly created pointer.
170    fn create_pointer(
171        &self,
172        value: DIFValueContainer,
173        allowed_type: Option<DIFTypeContainer>,
174        mutability: ReferenceMutability,
175    ) -> Result<PointerAddress, DIFCreatePointerError>;
176
177    /// Resolves a pointer address of a pointer that may not be in memory.
178    /// If the pointer is not in memory, it will be loaded from external storage.
179    fn resolve_pointer_address_external(
180        &self,
181        address: PointerAddress,
182    ) -> impl Future<Output = Result<DIFReference, DIFResolveReferenceError>>;
183
184    /// Resolves a pointer address of a pointer that is currently in memory.
185    /// Returns an error if the pointer is not found in memory.
186    fn resolve_pointer_address_in_memory(
187        &self,
188        address: PointerAddress,
189    ) -> Result<DIFReference, DIFResolveReferenceError>;
190
191    /// Starts observing changes to the pointer at the given address.
192    /// As long as the pointer is observed, it will not be garbage collected.
193    fn observe_pointer<F: Fn(&DIFUpdate) + 'static>(
194        &self,
195        transceiver_id: TransceiverId,
196        address: PointerAddress,
197        options: ObserveOptions,
198        observer: F,
199    ) -> Result<u32, DIFObserveError>;
200
201    /// Updates the options for an existing observer on the pointer at the given address.
202    /// If the observer does not exist, an error is returned.
203    fn update_observer_options(
204        &self,
205        address: PointerAddress,
206        observer_id: u32,
207        options: ObserveOptions,
208    ) -> Result<(), DIFObserveError>;
209
210    /// Stops observing changes to the pointer at the given address.
211    /// If no other references to the pointer exist, it may be garbage collected after this call.
212    fn unobserve_pointer(
213        &self,
214        address: PointerAddress,
215        observer_id: u32,
216    ) -> Result<(), DIFObserveError>;
217}