canic_host/subnet_registry/
mod.rs1use crate::{
2 icp::{IcpCli, IcpCommandError},
3 replica_query::{self, ReplicaQueryError},
4};
5use std::{error::Error, fmt, path::Path};
6
7const CANIC_SUBNET_REGISTRY_METHOD: &str = "canic_subnet_registry";
8const ICP_JSON_OUTPUT: &str = "json";
9
10#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct SubnetRegistryQuery {
16 pub source: SubnetRegistryQuerySource,
17 pub registry_json: String,
18}
19
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum SubnetRegistryQuerySource {
26 LocalReplica,
27 IcpCli,
28}
29
30#[derive(Debug)]
35pub enum SubnetRegistryQueryError {
36 Replica(ReplicaQueryError),
37 Icp(IcpCommandError),
38}
39
40impl fmt::Display for SubnetRegistryQueryError {
41 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match self {
43 Self::Replica(err) => write!(formatter, "{err}"),
44 Self::Icp(err) => write!(formatter, "{err}"),
45 }
46 }
47}
48
49impl Error for SubnetRegistryQueryError {
50 fn source(&self) -> Option<&(dyn Error + 'static)> {
51 match self {
52 Self::Replica(err) => Some(err),
53 Self::Icp(err) => Some(err),
54 }
55 }
56}
57
58impl From<ReplicaQueryError> for SubnetRegistryQueryError {
59 fn from(err: ReplicaQueryError) -> Self {
60 Self::Replica(err)
61 }
62}
63
64impl From<IcpCommandError> for SubnetRegistryQueryError {
65 fn from(err: IcpCommandError) -> Self {
66 Self::Icp(err)
67 }
68}
69
70pub fn query_subnet_registry_json(
72 icp: &IcpCli,
73 root: &str,
74 network: &str,
75 icp_root: Option<&Path>,
76 candid_path: Option<&Path>,
77) -> Result<SubnetRegistryQuery, SubnetRegistryQueryError> {
78 if replica_query::should_use_local_replica_query(Some(network)) {
79 return query_local_subnet_registry_json(root, network, icp_root);
80 }
81
82 let registry_json = icp.canister_query_output_with_candid(
83 root,
84 CANIC_SUBNET_REGISTRY_METHOD,
85 Some(ICP_JSON_OUTPUT),
86 candid_path,
87 )?;
88 Ok(SubnetRegistryQuery {
89 source: SubnetRegistryQuerySource::IcpCli,
90 registry_json,
91 })
92}
93
94fn query_local_subnet_registry_json(
95 root: &str,
96 network: &str,
97 icp_root: Option<&Path>,
98) -> Result<SubnetRegistryQuery, SubnetRegistryQueryError> {
99 let registry_json = icp_root.map_or_else(
100 || replica_query::query_subnet_registry_json(Some(network), root),
101 |root_path| {
102 replica_query::query_subnet_registry_json_from_root(Some(network), root, root_path)
103 },
104 )?;
105 Ok(SubnetRegistryQuery {
106 source: SubnetRegistryQuerySource::LocalReplica,
107 registry_json,
108 })
109}