icydb_core/interface/
query.rs

1use 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///
11/// QueryError
12///
13
14#[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
26/// Call the generated `icydb_query_load` method on the remote canister.
27pub async fn query_load(pid: Principal, query: LoadQuery) -> Result<Vec<Key>, Error> {
28    query_call(pid, "icydb_query_load", query).await
29}
30
31/// Call the generated `icydb_query_save` method on the remote canister.
32pub async fn query_save(pid: Principal, query: SaveQuery) -> Result<Key, Error> {
33    query_call(pid, "icydb_query_save", query).await
34}
35
36/// Call the generated `icydb_query_delete` method on the remote canister.
37pub async fn query_delete(pid: Principal, query: DeleteQuery) -> Result<Vec<Key>, Error> {
38    query_call(pid, "icydb_query_delete", query).await
39}
40
41// query_call
42// private helper method
43async 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}