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