Skip to main content

canic_host/canister_ready/
mod.rs

1//! Module: canister_ready
2//!
3//! Responsibility: query the maintained Canic readiness endpoint.
4//! Does not own: readiness state, local replica transport, or install orchestration.
5//! Boundary: selects one transport and decodes the canonical boolean response.
6
7use crate::{
8    icp::{IcpCli, IcpCommandError, IcpJsonResponseError, decode_json_response},
9    icp_config::IcpConfigError,
10    replica_query::{self, ReplicaQueryError},
11};
12use std::path::Path;
13use thiserror::Error as ThisError;
14
15const CANIC_READY_METHOD: &str = "canic_ready";
16const ICP_JSON_OUTPUT: &str = "json";
17
18///
19/// CanisterReadyQueryError
20///
21
22#[derive(Debug, ThisError)]
23pub enum CanisterReadyQueryError {
24    #[error(transparent)]
25    IcpConfig(#[from] IcpConfigError),
26
27    #[error(transparent)]
28    Icp(#[from] IcpCommandError),
29
30    #[error(transparent)]
31    Replica(#[from] ReplicaQueryError),
32
33    #[error(transparent)]
34    Response(#[from] IcpJsonResponseError),
35}
36
37/// Query `canic_ready`, using the local replica API for local environment targets.
38pub fn query_canister_ready(
39    icp: &IcpCli,
40    canister_id: &str,
41    environment: &str,
42    icp_root: Option<&Path>,
43    candid_path: Option<&Path>,
44) -> Result<bool, CanisterReadyQueryError> {
45    if replica_query::uses_local_replica_transport(Some(environment), icp_root)? {
46        return query_local_canister_ready(environment, canister_id, icp_root).map_err(Into::into);
47    }
48
49    query_canister_ready_with_icp(icp, canister_id, candid_path)
50}
51
52/// Query `canic_ready` directly through the local replica API.
53pub fn query_local_canister_ready(
54    environment: &str,
55    canister_id: &str,
56    icp_root: Option<&Path>,
57) -> Result<bool, ReplicaQueryError> {
58    replica_query::query_ready(Some(environment), canister_id, icp_root)
59}
60
61fn query_canister_ready_with_icp(
62    icp: &IcpCli,
63    canister_id: &str,
64    candid_path: Option<&Path>,
65) -> Result<bool, CanisterReadyQueryError> {
66    let output = icp.canister_query_output_with_candid(
67        canister_id,
68        CANIC_READY_METHOD,
69        Some(ICP_JSON_OUTPUT),
70        candid_path,
71    )?;
72    decode_json_response(&output).map_err(Into::into)
73}