1use std::{collections::BTreeMap, sync::Arc};
2
3use crate::{
4 procedure_object,
5 types::{XoObject, XoObjectMap},
6 RpcError,
7};
8
9use jsonrpsee_types::{traits::Client, v2::params::ParamsSer, JsonValue};
10use jsonrpsee_ws_client::WsClient;
11
12use crate::procedure_args;
13
14pub struct XoProcedures {
15 pub(crate) inner: Arc<WsClient>,
16}
17
18impl XoProcedures {
19 pub async fn get_all_objects<R: serde::de::DeserializeOwned>(
25 &self,
26 filter: impl Into<Option<serde_json::Map<String, JsonValue>>>,
27 limit: impl Into<Option<usize>>,
28 ) -> Result<R, RpcError> {
29 let args = match (filter.into(), limit.into()) {
30 (Some(filter), Some(limit)) => {
31 procedure_args! { "filter" => filter, "limit" => limit }
32 }
33 (Some(filter), None) => procedure_args! { "filter" => filter },
34 (None, Some(limit)) => procedure_args! { "limit" => limit },
35 (None, None) => procedure_args! {},
36 };
37
38 self.inner
39 .request("xo.getAllObjects", Some(ParamsSer::Map(args)))
40 .await
41 }
42
43 pub async fn get_objects<R: XoObjectMap>(
48 &self,
49 filter: impl Into<Option<serde_json::Map<String, JsonValue>>>,
50 limit: impl Into<Option<usize>>,
51 ) -> Result<R, RpcError> {
52 let mut filter = filter.into().unwrap_or_default();
53 filter.insert("type".to_string(), R::Object::OBJECT_TYPE.into());
54
55 self.get_all_objects(filter, limit).await
56 }
57
58 pub async fn get_object<R: XoObject>(
62 &self,
63 id: R::IdType,
64 ) -> Result<Option<R>, GetSingleObjectError>
65 where
66 R::IdType: Ord,
67 {
68 let filter = procedure_object!(
69 "id" => id.clone(),
70 "type" => R::OBJECT_TYPE.to_string()
71 );
72
73 let mut result: BTreeMap<R::IdType, R> = self
75 .get_all_objects(filter, Some(2))
76 .await
77 .map_err(GetSingleObjectError::Rpc)?;
78
79 match result.remove(&id) {
80 None => Ok(None),
81 Some(vm) if result.is_empty() => Ok(Some(vm)),
82 _ => Err(GetSingleObjectError::MultipleMatches),
83 }
84 }
85}
86
87#[derive(Debug)]
88pub enum GetSingleObjectError {
89 MultipleMatches,
90 Rpc(RpcError),
91}