orchestra_toolkit/session/api/avial/
fields.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 num_enum::TryFromPrimitive;
19
20use crate::{
21    taxonomy::*, CallError, Entity, InvalidResponse, Session, SessionAsync, SessionTrait,
22    String255, Token, Value,
23};
24
25use crate::session::api::macros::*;
26
27// ------------------------
28// -- Indexed operations --
29// ------------------------
30
31decl_call! {
32    InsertField(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
33    {
34        index: i64,
35        instance: i32,
36        deferred: bool,
37    }
38}
39impl<T: SessionTrait> InsertField<T> {
40    async fn call_async(self) -> Result<(), CallError> {
41        let _ = self
42            .session
43            .get_async_session()
44            .invoke_entity(self.entity, Method::Insert, self.authorization)
45            .with_aspect(Aspect::Field)
46            .with_attribute(self.attribute)
47            .with_name(self.name)
48            .with_value(&self.value)
49            .with_index(self.index)
50            .with_instance(self.instance)
51            .with_parameter(self.deferred as i64)
52            .await?;
53        Ok(())
54    }
55}
56
57decl_call! {
58    RemoveField(entity: Entity, attribute: Attribute, index: i64, authorization: Token) -> (),
59    {
60        instance: i32,
61        deferred: bool,
62    }
63}
64impl<T: SessionTrait> RemoveField<T> {
65    async fn call_async(self) -> Result<(), CallError> {
66        let _ = self
67            .session
68            .get_async_session()
69            .invoke_entity(self.entity, Method::Remove, self.authorization)
70            .with_aspect(Aspect::Field)
71            .with_attribute(self.attribute)
72            .with_index(self.index)
73            .with_instance(self.instance)
74            .with_parameter(self.deferred as i64)
75            .await?;
76        Ok(())
77    }
78}
79
80decl_call! {
81    ReplaceField(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
82    {
83        index: i64,
84        instance: i32,
85        deferred: bool,
86    }
87}
88impl<T: SessionTrait> ReplaceField<T> {
89    async fn call_async(self) -> Result<(), CallError> {
90        let _ = self
91            .session
92            .get_async_session()
93            .invoke_entity(self.entity, Method::Replace, self.authorization)
94            .with_aspect(Aspect::Field)
95            .with_attribute(self.attribute)
96            .with_name(self.name)
97            .with_value(&self.value)
98            .with_index(self.index)
99            .with_instance(self.instance)
100            .with_parameter(self.deferred as i64)
101            .await?;
102        Ok(())
103    }
104}
105
106decl_call! {
107    FindField(entity: Entity, attribute: Attribute, value: Value, authorization: Token) -> i64,
108    {
109        index: i64,
110        instance: i32,
111    }
112}
113impl<T: SessionTrait> FindField<T> {
114    async fn call_async(self) -> Result<i64, CallError> {
115        let res = self
116            .session
117            .get_async_session()
118            .invoke_entity(self.entity, Method::Find, self.authorization)
119            .with_aspect(Aspect::Field)
120            .with_attribute(self.attribute)
121            .with_value(&self.value)
122            .with_index(self.index)
123            .with_instance(self.instance)
124            .await?;
125        Ok(res.integer()?)
126    }
127}
128
129// -----------------------
130// -- Mapped operations --
131// -----------------------
132
133decl_call! {
134    IncludeField(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
135    {
136        deferred: bool,
137    }
138}
139impl<T: SessionTrait> IncludeField<T> {
140    async fn call_async(self) -> Result<(), CallError> {
141        let _ = self
142            .session
143            .get_async_session()
144            .invoke_entity(self.entity, Method::Include, self.authorization)
145            .with_aspect(Aspect::Field)
146            .with_attribute(self.attribute)
147            .with_name(self.name)
148            .with_value(&self.value)
149            .with_parameter(self.deferred as i64)
150            .await?;
151        Ok(())
152    }
153}
154
155decl_call! {
156    ExcludeField(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> (),
157    {
158        deferred: bool,
159    }
160}
161impl<T: SessionTrait> ExcludeField<T> {
162    async fn call_async(self) -> Result<(), CallError> {
163        let _ = self
164            .session
165            .get_async_session()
166            .invoke_entity(self.entity, Method::Exclude, self.authorization)
167            .with_aspect(Aspect::Field)
168            .with_attribute(self.attribute)
169            .with_name(self.name)
170            .with_parameter(self.deferred as i64)
171            .await?;
172        Ok(())
173    }
174}
175
176// -----------------------
177// -- Hybrid operations --
178// -----------------------
179
180decl_call! {
181    SetField(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
182    {
183        deferred: bool,
184    }
185}
186impl<T: SessionTrait> SetField<T> {
187    async fn call_async(self) -> Result<(), CallError> {
188        let _ = self
189            .session
190            .get_async_session()
191            .invoke_entity(self.entity, Method::Set, self.authorization)
192            .with_aspect(Aspect::Field)
193            .with_attribute(self.attribute)
194            .with_name(self.name)
195            .with_value(&self.value)
196            .with_parameter(self.deferred as i64)
197            .await?;
198        Ok(())
199    }
200}
201
202decl_call! {
203    GetField(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> Value,
204    {
205    }
206}
207impl<T: SessionTrait> GetField<T> {
208    async fn call_async(self) -> Result<Value, CallError> {
209        self.session
210            .get_async_session()
211            .invoke_entity(self.entity, Method::Get, self.authorization)
212            .with_aspect(Aspect::Field)
213            .with_attribute(self.attribute)
214            .with_name(self.name)
215            .await
216    }
217}
218
219decl_call! {
220    ClearField(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> (),
221    {
222        deferred: bool,
223    }
224}
225impl<T: SessionTrait> ClearField<T> {
226    async fn call_async(self) -> Result<(), CallError> {
227        let _ = self
228            .session
229            .get_async_session()
230            .invoke_entity(self.entity, Method::Clear, self.authorization)
231            .with_aspect(Aspect::Field)
232            .with_attribute(self.attribute)
233            .with_name(self.name)
234            .with_parameter(self.deferred as i64)
235            .await?;
236        Ok(())
237    }
238}
239
240// -----------------------
241// -- Utility functions --
242// -----------------------
243
244decl_call! {
245    FieldCount(entity: Entity, attribute: Attribute, authorization: Token) -> i64,
246    {
247        instance: i32,
248    }
249}
250impl<T: SessionTrait> FieldCount<T> {
251    async fn call_async(self) -> Result<i64, CallError> {
252        let res = self
253            .session
254            .get_async_session()
255            .invoke_entity(self.entity, Method::Count, self.authorization)
256            .with_aspect(Aspect::Field)
257            .with_attribute(self.attribute)
258            .with_instance(self.instance)
259            .await?;
260        Ok(res.integer()?)
261    }
262}
263
264decl_call! {
265    FieldMember(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> bool,
266    {
267        instance: i32,
268    }
269}
270impl<T: SessionTrait> FieldMember<T> {
271    async fn call_async(self) -> Result<bool, CallError> {
272        let res = self
273            .session
274            .get_async_session()
275            .invoke_entity(self.entity, Method::Member, self.authorization)
276            .with_aspect(Aspect::Field)
277            .with_attribute(self.attribute)
278            .with_name(self.name)
279            .with_instance(self.instance)
280            .await?;
281        Ok(res.boolean()?)
282    }
283}
284
285decl_call! {
286    FieldName(entity: Entity, attribute: Attribute, index: i64, authorization: Token) -> String255,
287    {
288        instance: i32,
289    }
290}
291impl<T: SessionTrait> FieldName<T> {
292    async fn call_async(self) -> Result<String255, CallError> {
293        let res = self
294            .session
295            .get_async_session()
296            .invoke_entity(self.entity, Method::Name, self.authorization)
297            .with_aspect(Aspect::Field)
298            .with_attribute(self.attribute)
299            .with_index(self.index)
300            .with_instance(self.instance)
301            .await?;
302        Ok(res
303            .string()?
304            .try_into()
305            .map_err(|e| CallError::InvalidResponse(InvalidResponse::Name(e)))?)
306    }
307}
308
309decl_call! {
310    FieldKey(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> String255,
311    {
312        index: i64,
313        instance: i32,
314    }
315}
316impl<T: SessionTrait> FieldKey<T> {
317    async fn call_async(self) -> Result<String255, CallError> {
318        let res = self
319            .session
320            .get_async_session()
321            .invoke_entity(self.entity, Method::Key, self.authorization)
322            .with_aspect(Aspect::Field)
323            .with_attribute(self.attribute)
324            .with_name(self.name)
325            .with_index(self.index)
326            .with_instance(self.instance)
327            .await?;
328        Ok(res
329            .string()?
330            .try_into()
331            .map_err(|e| CallError::InvalidResponse(InvalidResponse::Key(e)))?)
332    }
333}
334
335decl_call! {
336    FieldValue(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> Value,
337    {
338        index: i64,
339        instance: i32,
340    }
341}
342impl<T: SessionTrait> FieldValue<T> {
343    async fn call_async(self) -> Result<Value, CallError> {
344        self.session
345            .get_async_session()
346            .invoke_entity(self.entity, Method::Value, self.authorization)
347            .with_aspect(Aspect::Field)
348            .with_attribute(self.attribute)
349            .with_name(self.name)
350            .with_index(self.index)
351            .with_instance(self.instance)
352            .await
353    }
354}
355
356decl_call! {
357    FieldIndex(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> i64,
358    {
359        instance: i32,
360    }
361}
362impl<T: SessionTrait> FieldIndex<T> {
363    async fn call_async(self) -> Result<i64, CallError> {
364        let res = self
365            .session
366            .get_async_session()
367            .invoke_entity(self.entity, Method::Index, self.authorization)
368            .with_aspect(Aspect::Field)
369            .with_attribute(self.attribute)
370            .with_name(self.name)
371            .with_instance(self.instance)
372            .await?;
373        Ok(res.integer()?)
374    }
375}
376
377decl_call! {
378    // Just use FactAttribute
379    FieldAttribute(entity: Entity, authorization: Token) -> Attribute,
380    {
381        name: String255,
382        index: i64,
383        instance: i32,
384    }
385}
386impl<T: SessionTrait> FieldAttribute<T> {
387    async fn call_async(self) -> Result<Attribute, CallError> {
388        let res = self
389            .session
390            .get_async_session()
391            .invoke_entity(self.entity, Method::Attribute, self.authorization)
392            .with_aspect(Aspect::Field)
393            .with_name(self.name)
394            .with_index(self.index)
395            .with_instance(self.instance)
396            .await?;
397        let num64 = res.integer()?;
398        let num16 = u16::try_from(num64).map_err(|_| InvalidResponse::Attribute(num64))?;
399        let attr =
400            Attribute::try_from_primitive(num16).map_err(|_| InvalidResponse::Attribute(num64))?;
401        Ok(attr)
402    }
403}
404
405// --------------------------
406// -- Plurality operations --
407// --------------------------
408
409decl_call! {
410    SortFields(entity: Entity, attribute: Attribute, authorization: Token) -> (),
411    {
412        instance: i32,
413        deferred: bool,
414    }
415}
416impl<T: SessionTrait> SortFields<T> {
417    async fn call_async(self) -> Result<(), CallError> {
418        let _ = self
419            .session
420            .get_async_session()
421            .invoke_entity(self.entity, Method::Sort, self.authorization)
422            .with_aspect(Aspect::Field)
423            .with_attribute(self.attribute)
424            .with_instance(self.instance)
425            .with_parameter(self.deferred as i64)
426            .await?;
427        Ok(())
428    }
429}
430
431decl_call! {
432    PurgeFields(entity: Entity, attribute: Attribute, authorization: Token) -> (),
433    {
434        instance: i32,
435        deferred: bool,
436    }
437}
438impl<T: SessionTrait> PurgeFields<T> {
439    async fn call_async(self) -> Result<(), CallError> {
440        let _ = self
441            .session
442            .get_async_session()
443            .invoke_entity(self.entity, Method::Purge, self.authorization)
444            .with_aspect(Aspect::Field)
445            .with_attribute(self.attribute)
446            .with_instance(self.instance)
447            .with_parameter(self.deferred as i64)
448            .await?;
449        Ok(())
450    }
451}
452
453decl_call! {
454    RetrieveFields(entity: Entity, attribute: Attribute, authorization: Token) -> String,
455    {
456        instance: i32,
457    }
458}
459impl<T: SessionTrait> RetrieveFields<T> {
460    async fn call_async(self) -> Result<String, CallError> {
461        let res = self
462            .session
463            .get_async_session()
464            .invoke_entity(self.entity, Method::Retrieve, self.authorization)
465            .with_aspect(Aspect::Field)
466            .with_attribute(self.attribute)
467            .with_instance(self.instance)
468            .await?;
469        Ok(res.interchange()?)
470    }
471}