orchestra_toolkit/session/api/avial/
facets.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    InsertFacet(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> InsertFacet<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::Facet)
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    RemoveFacet(entity: Entity, attribute: Attribute, index: i64, authorization: Token) -> (),
59    {
60        instance: i32,
61        deferred: bool,
62    }
63}
64impl<T: SessionTrait> RemoveFacet<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::Facet)
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    ReplaceFacet(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
82    {
83        instance: i32,
84        index: i64,
85        deferred: bool,
86    }
87}
88impl<T: SessionTrait> ReplaceFacet<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::Facet)
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    FindFacet(entity: Entity, attribute: Attribute, value: Value, authorization: Token) -> i64,
108    {
109        index: i64,
110        instance: i32,
111    }
112}
113impl<T: SessionTrait> FindFacet<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::Facet)
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    IncludeFacet(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
135    {
136        deferred: bool,
137    }
138}
139impl<T: SessionTrait> IncludeFacet<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::Facet)
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    ExcludeFacet(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> (),
157    {
158        deferred: bool,
159    }
160}
161impl<T: SessionTrait> ExcludeFacet<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::Facet)
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    SetFacet(entity: Entity, attribute: Attribute, name: String255, value: Value, authorization: Token) -> (),
182    {
183        deferred: bool,
184    }
185}
186impl<T: SessionTrait> SetFacet<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::Facet)
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    GetFacet(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> Value,
204    {
205    }
206}
207impl<T: SessionTrait> GetFacet<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::Facet)
213            .with_attribute(self.attribute)
214            .with_name(self.name)
215            .await
216    }
217}
218
219decl_call! {
220    ClearFacet(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> (),
221    {
222        deferred: bool,
223    }
224}
225impl<T: SessionTrait> ClearFacet<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::Facet)
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    FacetCount(entity: Entity, attribute: Attribute, authorization: Token) -> i64,
246    {
247        instance: i32,
248    }
249}
250impl<T: SessionTrait> FacetCount<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::Facet)
257            .with_attribute(self.attribute)
258            .with_instance(self.instance)
259            .await?;
260        Ok(res.integer()?)
261    }
262}
263
264decl_call! {
265    FacetMember(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> bool,
266    {
267        instance: i32,
268    }
269}
270impl<T: SessionTrait> FacetMember<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::Facet)
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    FacetName(entity: Entity, attribute: Attribute, index: i64, authorization: Token) -> String255,
287    {
288        instance: i32,
289    }
290}
291impl<T: SessionTrait> FacetName<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::Facet)
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    FacetKey(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> String255,
311    {
312        index: i64,
313        instance: i32,
314    }
315}
316impl<T: SessionTrait> FacetKey<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::Facet)
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    FacetValue(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> Value,
337    {
338        index: i64,
339        instance: i32,
340    }
341}
342impl<T: SessionTrait> FacetValue<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::Facet)
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    FacetIndex(entity: Entity, attribute: Attribute, name: String255, authorization: Token) -> i64,
358    {
359        instance: i32,
360    }
361}
362impl<T: SessionTrait> FacetIndex<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::Facet)
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    FacetAttribute(entity: Entity,  authorization: Token) -> Attribute,
380    {
381        name: String255,
382        index: i64,
383        instance: i32,
384    }
385}
386impl<T: SessionTrait> FacetAttribute<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::Facet)
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    SortFacets(entity: Entity, attribute: Attribute, authorization: Token) -> (),
411    {
412        instance: i32,
413        deferred: bool,
414    }
415}
416
417impl<T: SessionTrait> SortFacets<T> {
418    async fn call_async(self) -> Result<(), CallError> {
419        let _ = self
420            .session
421            .get_async_session()
422            .invoke_entity(self.entity, Method::Sort, self.authorization)
423            .with_aspect(Aspect::Facet)
424            .with_attribute(self.attribute)
425            .with_instance(self.instance)
426            .with_parameter(self.deferred as i64)
427            .await?;
428        Ok(())
429    }
430}
431
432decl_call! {
433    PurgeFacets(entity: Entity, attribute: Attribute, authorization: Token) -> (),
434    {
435        instance: i32,
436        deferred: bool,
437    }
438}
439impl<T: SessionTrait> PurgeFacets<T> {
440    async fn call_async(self) -> Result<(), CallError> {
441        let _ = self
442            .session
443            .get_async_session()
444            .invoke_entity(self.entity, Method::Purge, self.authorization)
445            .with_aspect(Aspect::Facet)
446            .with_attribute(self.attribute)
447            .with_instance(self.instance)
448            .with_parameter(self.deferred as i64)
449            .await?;
450        Ok(())
451    }
452}
453
454decl_call! {
455    RetrieveFacets(entity: Entity, attribute: Attribute, authorization: Token) -> String,
456    {
457        instance: i32,
458    }
459}
460impl<T: SessionTrait> RetrieveFacets<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::Facet)
467            .with_attribute(self.attribute)
468            .with_instance(self.instance)
469            .await?;
470        Ok(res.interchange()?)
471        // TODO: return Vec<Facet> ?
472    }
473}