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