orchestra_toolkit/session/api/
avial.rs

1/* Copyright 2024-2025 LEDR Technologies Inc.
2* This file is part of the Orchestra library, which helps developer use our Orchestra technology which is based on AvesTerra, owned and developped by Georgetown University, under license agreement with LEDR Technologies Inc.
3*
4* The Orchestra library is a free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
5*
6* The Orchestra library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
7*
8* You should have received a copy of the GNU Lesser General Public License along with the Orchestra library. If not, see <https://www.gnu.org/licenses/>.
9*
10* If you have any questions, feedback or issues about the Orchestra library, you can contact us at support@ledr.io.
11*/
12
13use std::{
14    future::{Future, IntoFuture},
15    pin::Pin,
16};
17
18use crate::{
19    taxonomy::*, AvialModel, CallError, Entity, InvalidResponse, Locutor, Session, SessionAsync,
20    SessionTrait, String255, Token, Value,
21};
22
23use super::macros::*;
24
25mod annotations;
26mod create_outlet;
27mod facets;
28mod factors;
29mod facts;
30mod features;
31mod fields;
32mod frames;
33mod properties;
34mod registries;
35
36decl_call! {
37    SaveEntity(entity: Entity, authorization: Token) -> (),
38    {
39    }
40}
41impl<T: SessionTrait> SaveEntity<T> {
42    pub async fn call_async(self) -> Result<(), CallError> {
43        self.session
44            .get_async_session()
45            .invoke_entity(self.entity, Method::Save, self.authorization)
46            .await?;
47        Ok(())
48    }
49}
50
51decl_call! {
52    RestoreEntity(entity: Entity, authorization: Token) -> (),
53    {
54    }
55}
56impl<T: SessionTrait> RestoreEntity<T> {
57    pub async fn call_async(self) -> Result<(), CallError> {
58        self.session
59            .get_async_session()
60            .invoke_entity(self.entity, Method::Load, self.authorization)
61            .await?;
62        Ok(())
63    }
64}
65
66decl_call! {
67    RetrieveEntity(entity: Entity, authorization: Token) -> AvialModel,
68    {
69    }
70}
71impl<T: SessionTrait> RetrieveEntity<T> {
72    pub async fn call_async(self) -> Result<AvialModel, CallError> {
73        let val = self
74            .session
75            .get_async_session()
76            .invoke_entity(self.entity, Method::Retrieve, self.authorization)
77            .await?;
78        let interchange = val.interchange().map_err(InvalidResponse::ValueTag)?;
79        Ok(serde_json::from_str(&interchange).map_err(InvalidResponse::ValueDeser)?)
80    }
81}
82
83decl_call! {
84    StoreEntity(entity: Entity, model: AvialModel, authorization: Token) -> (),
85    {
86        mode: Mode,
87    }
88}
89impl<T: SessionTrait> StoreEntity<T> {
90    pub async fn call_async(self) -> Result<(), CallError> {
91        // UNWRAP SAFETY:
92        // serde_json::to_string documentation states:
93        //
94        // > Serialization can fail if `T`'s implementation of `Serialize` decides to
95        // > fail, or if `T` contains a map with non-string keys.
96        //
97        // We control the `AvialModel` type and it is guaranteed to be serializable.
98        let val = Value::Interchange(serde_json::to_string(&self.model).unwrap());
99        self.session
100            .get_async_session()
101            .invoke_entity(self.entity, Method::Store, self.authorization)
102            .with_mode(self.mode)
103            .with_value(&val)
104            .await?;
105        Ok(())
106    }
107}
108
109decl_call! {
110    PurgeEntity(entity: Entity, authorization: Token) -> (),
111    {
112        instance: i32,
113    }
114}
115impl<T: SessionTrait> PurgeEntity<T> {
116    pub async fn call_async(self) -> Result<(), CallError> {
117        self.session
118            .get_async_session()
119            .invoke_entity(self.entity, Method::Purge, self.authorization)
120            .with_instance(self.instance)
121            .await?;
122        Ok(())
123    }
124}
125
126decl_call! {
127    Redirect(from: Entity, to: Entity, authorization: Token) -> (),
128    {
129        server: Entity,
130    }
131}
132impl<T: SessionTrait> Redirect<T> {
133    pub async fn call_async(self) -> Result<(), CallError> {
134        self.session
135            .get_async_session()
136            .entity_redirect(self.from, self.to, self.authorization)
137            .with_server(self.server)
138            .await?;
139        Ok(())
140    }
141}
142
143decl_call! {
144    CreateOutlet(name: String255, authorization: Token) -> Entity,
145    {
146        outlet: Entity,
147        server: Entity,
148        key: String255,
149        context: Context,
150        category: Category,
151        class: Class,
152        method: Method,
153        attribute: Attribute,
154        event: Event,
155        precedence: u16,
156        timeout: i64,
157    }
158}
159impl<T: SessionTrait> CreateOutlet<T> {
160    async fn call_async(self) -> Result<Entity, CallError> {
161        let session = self.session.get_async_session();
162
163        let e = session
164            .create_entity(self.name, self.authorization)
165            .with_outlet(self.outlet)
166            .with_server(self.server)
167            .with_key(self.key)
168            .with_context(self.context)
169            .with_category(self.category)
170            .with_class(self.class)
171            .with_method(self.method)
172            .with_attribute(self.attribute)
173            .with_event(self.event)
174            .with_precedence(self.precedence)
175            .with_timeout(self.timeout)
176            .await?;
177
178        session.activate_outlet(e, self.authorization).await?;
179
180        Ok(e)
181    }
182}
183
184decl_call! {
185    CreateObject(name: String255, authorization: Token) -> Entity,
186    {
187        key: String255,
188        value: Value,
189        context: Context,
190        category: Category,
191        class: Class,
192        mode: Mode,
193        outlet: Entity,
194        server: Entity,
195    }
196}
197impl<T: SessionTrait> CreateObject<T> {
198    async fn call_async(self) -> Result<Entity, CallError> {
199        let session = self.session.get_async_session();
200
201        let outlet = match self.outlet {
202            Entity::NULL => Entity::new(0, 0, 11),
203            e => e,
204        };
205
206        let e = session
207            .invoke_entity(outlet, Method::Create, self.authorization)
208            .with_name(self.name)
209            .with_key(self.key)
210            .with_value(&self.value)
211            .with_context(self.context)
212            .with_category(self.category)
213            .with_class(self.class)
214            .with_mode(self.mode)
215            .with_ancillary(self.server)
216            .await?;
217
218        Ok(e.entity()?)
219    }
220}
221
222decl_call! {
223    DeleteObject(object: Entity, authorization: Token) -> (),
224    {}
225}
226impl<T: SessionTrait> DeleteObject<T> {
227    async fn call_async(self) -> Result<(), CallError> {
228        let session = self.session.get_async_session();
229
230        session
231            .invoke_entity(self.object, Method::Delete, self.authorization)
232            .await?;
233
234        Ok(())
235    }
236}
237
238decl_call! {
239    CreateGeneral(name: String255, authorization: Token) -> Entity,
240    {
241        key: String255,
242        value: Value,
243        context: Context,
244        category: Category,
245        class: Class,
246        mode: Mode,
247        outlet: Entity,
248        server: Entity,
249    }
250}
251impl<T: SessionTrait> CreateGeneral<T> {
252    async fn call_async(self) -> Result<Entity, CallError> {
253        let session = self.session.get_async_session();
254
255        let outlet = match self.outlet {
256            Entity::NULL => Entity::new(0, 0, 14),
257            e => e,
258        };
259
260        let e = session
261            .invoke_entity(outlet, Method::Create, self.authorization)
262            .with_name(self.name)
263            .with_key(self.key)
264            .with_value(&self.value)
265            .with_context(self.context)
266            .with_category(self.category)
267            .with_class(self.class)
268            .with_mode(self.mode)
269            .with_ancillary(self.server)
270            .await?;
271
272        Ok(e.entity()?)
273    }
274}
275
276decl_call! {
277    DeleteGeneral(general: Entity, authorization: Token) -> (),
278    {}
279}
280impl<T: SessionTrait> DeleteGeneral<T> {
281    async fn call_async(self) -> Result<(), CallError> {
282        let session = self.session.get_async_session();
283
284        session
285            .invoke_entity(self.general, Method::Delete, self.authorization)
286            .await?;
287
288        Ok(())
289    }
290}
291
292decl_call! {
293    InvokeLocutor(locutor: Locutor) -> Value,
294    {}
295}
296impl<T: SessionTrait> InvokeLocutor<T> {
297    async fn call_async(self) -> Result<Value, CallError> {
298        let session = self.session.get_async_session();
299
300        session
301            .invoke_entity(
302                self.locutor.entity,
303                self.locutor.method,
304                self.locutor.authorization,
305            )
306            .with_auxiliary(self.locutor.auxiliary)
307            .with_ancillary(self.locutor.ancillary)
308            .with_attribute(self.locutor.attribute)
309            .with_instance(self.locutor.instance)
310            .with_offset(self.locutor.offset)
311            .with_name(self.locutor.name)
312            .with_key(self.locutor.key)
313            .with_value(&self.locutor.value)
314            .with_parameter(self.locutor.parameter)
315            .with_resultant(self.locutor.resultant)
316            .with_index(self.locutor.index)
317            .with_count(self.locutor.count)
318            .with_aspect(self.locutor.aspect)
319            .with_context(self.locutor.context)
320            .with_category(self.locutor.category)
321            .with_class(self.locutor.class)
322            .with_event(self.locutor.event)
323            .with_mode(self.locutor.mode)
324            .with_state(self.locutor.state)
325            .with_condition(self.locutor.condition)
326            .with_precedence(self.locutor.precedence)
327            .with_time(self.locutor.time)
328            .with_timeout(self.locutor.timeout)
329            .with_authority(self.locutor.authority)
330            .await
331    }
332}