Skip to main content

ic_query/subnet_catalog/resolver/
model.rs

1//! Module: subnet_catalog::resolver::model
2//!
3//! Defines resolver options and outputs for subnet catalog lookups.
4
5use crate::subnet_catalog::{RoutingRange, SubnetCatalogProvenance, SubnetInfo};
6use candid::Principal;
7use serde::{Deserialize, Serialize};
8use std::str::FromStr;
9
10///
11/// ResolveAs
12///
13/// Caller-requested interpretation for an ambiguous principal input.
14///
15
16#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
17#[serde(rename_all = "snake_case")]
18pub enum ResolveAs {
19    /// Resolve the input as a subnet principal.
20    Subnet,
21    /// Resolve the input as a canister principal.
22    Canister,
23}
24
25impl ResolveAs {
26    /// Returns the stable snake_case value used in CLI options and reports.
27    #[must_use]
28    pub const fn as_str(self) -> &'static str {
29        match self {
30            Self::Subnet => "subnet",
31            Self::Canister => "canister",
32        }
33    }
34}
35
36impl FromStr for ResolveAs {
37    type Err = String;
38
39    fn from_str(value: &str) -> Result<Self, Self::Err> {
40        match value {
41            "subnet" => Ok(Self::Subnet),
42            "canister" => Ok(Self::Canister),
43            other => Err(format!("invalid value {other}; use subnet or canister")),
44        }
45    }
46}
47
48///
49/// ResolvedSubnetSubject
50///
51/// Subject type chosen by the resolver.
52///
53
54#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
55#[serde(rename_all = "snake_case")]
56pub enum ResolvedSubnetSubject {
57    /// Resolver matched a subnet principal.
58    Subnet,
59    /// Resolver matched a canister principal through routing ranges.
60    Canister,
61}
62
63impl ResolvedSubnetSubject {
64    /// Returns the stable snake_case value used in reports.
65    #[must_use]
66    pub const fn as_str(self) -> &'static str {
67        match self {
68            Self::Subnet => "subnet",
69            Self::Canister => "canister",
70        }
71    }
72}
73
74///
75/// ResolvedSubnet
76///
77/// Resolved subnet match and the evidence used to produce it.
78///
79
80#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
81pub struct ResolvedSubnet {
82    pub input_principal: String,
83    pub resolved_as: ResolvedSubnetSubject,
84    pub resolved_from: String,
85    pub subnet: SubnetInfo,
86    pub matched_canister_principal: Option<String>,
87    pub matched_routing_range: Option<RoutingRange>,
88    /// Lowercase SHA-256 digest of the raw catalog supplying the match.
89    pub catalog_digest: String,
90    /// Complete provenance supplied by the raw catalog.
91    pub provenance: SubnetCatalogProvenance,
92}
93
94///
95/// ResolvedCanisterRoute
96///
97/// Authority-bearing route tied to the exact validated catalog that proved it.
98///
99
100#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
101pub struct ResolvedCanisterRoute {
102    /// Canonical canister principal resolved through the routing table.
103    pub canister: Principal,
104    /// Canonical target Subnet principal.
105    pub subnet: Principal,
106    /// Complete validated Subnet classification matched by the route.
107    pub subnet_info: SubnetInfo,
108    /// Inclusive validated range containing the canister principal.
109    pub matched_range: RoutingRange,
110    /// Exact Registry version of the validated catalog.
111    pub registry_version: u64,
112    /// Binary SHA-256 digest of the validated catalog authority payload.
113    pub catalog_digest: [u8; 32],
114    /// Complete provenance of the validated catalog.
115    pub provenance: SubnetCatalogProvenance,
116}