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