datex_core/dif/
interface.rs

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