icydb_core/interface/
query.rs1use crate::{
2 Error, Key,
3 db::query::{DeleteQuery, LoadQuery, SaveQuery},
4 interface::InterfaceError,
5};
6use candid::Principal;
7use canic::{Error as CanicError, cdk::call::Call};
8use thiserror::Error as ThisError;
9
10#[derive(Debug, ThisError)]
15pub enum QueryError {
16 #[error("entity not found: {0}")]
17 EntityNotFound(String),
18}
19
20impl From<QueryError> for Error {
21 fn from(err: QueryError) -> Self {
22 InterfaceError::from(err).into()
23 }
24}
25
26pub async fn query_load(pid: Principal, query: LoadQuery) -> Result<Vec<Key>, Error> {
28 query_call(pid, "icydb_query_load", query).await
29}
30
31pub async fn query_save(pid: Principal, query: SaveQuery) -> Result<Key, Error> {
33 query_call(pid, "icydb_query_save", query).await
34}
35
36pub async fn query_delete(pid: Principal, query: DeleteQuery) -> Result<Vec<Key>, Error> {
38 query_call(pid, "icydb_query_delete", query).await
39}
40
41async fn query_call<T: candid::CandidType + for<'de> candid::Deserialize<'de>>(
44 pid: Principal,
45 method: &str,
46 arg: impl candid::CandidType,
47) -> Result<T, Error> {
48 let result = Call::unbounded_wait(pid, method)
49 .with_arg(arg)
50 .await
51 .map_err(CanicError::from)?;
52
53 let response = result.candid::<T>().map_err(CanicError::from)?;
54
55 Ok(response)
56}