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