canic_host/canister_ready/
mod.rs1use crate::{
8 icp::{IcpCli, IcpCommandError, IcpJsonResponseError, decode_json_response},
9 replica_query::{self, ReplicaQueryError},
10};
11use std::{error::Error, fmt, path::Path};
12
13const CANIC_READY_METHOD: &str = "canic_ready";
14const ICP_JSON_OUTPUT: &str = "json";
15
16#[derive(Debug)]
21pub enum CanisterReadyQueryError {
22 Icp(IcpCommandError),
23 Replica(ReplicaQueryError),
24 Response(IcpJsonResponseError),
25}
26
27impl fmt::Display for CanisterReadyQueryError {
28 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match self {
30 Self::Icp(err) => write!(formatter, "{err}"),
31 Self::Replica(err) => write!(formatter, "{err}"),
32 Self::Response(err) => write!(formatter, "{err}"),
33 }
34 }
35}
36
37impl Error for CanisterReadyQueryError {
38 fn source(&self) -> Option<&(dyn Error + 'static)> {
39 match self {
40 Self::Icp(err) => Some(err),
41 Self::Replica(err) => Some(err),
42 Self::Response(err) => Some(err),
43 }
44 }
45}
46
47impl From<IcpCommandError> for CanisterReadyQueryError {
48 fn from(err: IcpCommandError) -> Self {
49 Self::Icp(err)
50 }
51}
52
53impl From<ReplicaQueryError> for CanisterReadyQueryError {
54 fn from(err: ReplicaQueryError) -> Self {
55 Self::Replica(err)
56 }
57}
58
59impl From<IcpJsonResponseError> for CanisterReadyQueryError {
60 fn from(err: IcpJsonResponseError) -> Self {
61 Self::Response(err)
62 }
63}
64
65pub fn query_canister_ready(
67 icp: &IcpCli,
68 canister_id: &str,
69 network: &str,
70 icp_root: Option<&Path>,
71 candid_path: Option<&Path>,
72) -> Result<bool, CanisterReadyQueryError> {
73 if replica_query::should_use_local_replica_query(Some(network)) {
74 return query_local_canister_ready(network, canister_id, icp_root).map_err(Into::into);
75 }
76
77 query_canister_ready_with_icp(icp, canister_id, candid_path)
78}
79
80pub fn query_local_canister_ready(
82 network: &str,
83 canister_id: &str,
84 icp_root: Option<&Path>,
85) -> Result<bool, ReplicaQueryError> {
86 icp_root.map_or_else(
87 || replica_query::query_ready(Some(network), canister_id),
88 |root| replica_query::query_ready_from_root(Some(network), canister_id, root),
89 )
90}
91
92fn query_canister_ready_with_icp(
93 icp: &IcpCli,
94 canister_id: &str,
95 candid_path: Option<&Path>,
96) -> Result<bool, CanisterReadyQueryError> {
97 let output = icp.canister_query_output_with_candid(
98 canister_id,
99 CANIC_READY_METHOD,
100 Some(ICP_JSON_OUTPUT),
101 candid_path,
102 )?;
103 decode_json_response(&output).map_err(Into::into)
104}