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 /// Canonical principal resolved from the supplied subject.
83 pub input_principal: String,
84 /// Whether resolution treated the subject as a Subnet or a canister.
85 pub resolved_as: ResolvedSubnetSubject,
86 /// Resolution evidence label: a Subnet principal match or a routing range.
87 pub resolved_from: String,
88 /// Resolved Subnet record with its Registry type and classification annotations.
89 pub subnet: SubnetInfo,
90 /// Exact canonical canister principal for a canister subject; absent for a Subnet subject.
91 pub matched_canister_principal: Option<String>,
92 /// Inclusive routing authority range used for a canister subject.
93 pub matched_routing_range: Option<RoutingRange>,
94 /// Lowercase SHA-256 digest of the raw catalog supplying the match.
95 pub catalog_digest: String,
96 /// Complete provenance supplied by the raw catalog.
97 pub provenance: SubnetCatalogProvenance,
98}
99
100///
101/// ResolvedCanisterRoute
102///
103/// Authority-bearing route tied to the exact validated catalog that proved it.
104///
105
106#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
107pub struct ResolvedCanisterRoute {
108 /// Canonical canister principal resolved through the routing table.
109 pub canister: Principal,
110 /// Canonical target Subnet principal.
111 pub subnet: Principal,
112 /// Complete validated Subnet classification matched by the route.
113 pub subnet_info: SubnetInfo,
114 /// Inclusive validated range containing the canister principal.
115 pub matched_range: RoutingRange,
116 /// Exact Registry version of the validated catalog.
117 pub registry_version: u64,
118 /// Binary SHA-256 digest of the validated catalog authority payload.
119 pub catalog_digest: [u8; 32],
120 /// Complete provenance of the validated catalog.
121 pub provenance: SubnetCatalogProvenance,
122}