canic_core/ops/
config.rs

1use crate::{
2    Error,
3    config::{
4        Config,
5        schema::{CanisterConfig, SubnetConfig},
6    },
7    ids::{CanisterRole, SubnetRole},
8    ops::{
9        OpsError,
10        storage::env::{EnvOps, EnvOpsError},
11    },
12};
13use thiserror::Error as ThisError;
14
15///
16/// ConfigOpsError
17///
18
19#[derive(Debug, ThisError)]
20pub enum ConfigOpsError {
21    #[error("subnet {0} not found in configuration")]
22    SubnetNotFound(String),
23
24    #[error("canister {0} not defined in subnet {1}")]
25    CanisterNotFound(String, String),
26
27    #[error(transparent)]
28    EnvOpsError(#[from] EnvOpsError),
29}
30
31impl From<ConfigOpsError> for Error {
32    fn from(err: ConfigOpsError) -> Self {
33        OpsError::from(err).into()
34    }
35}
36
37///
38/// ConfigOps
39///
40/// Ops-layer façade for configuration access.
41///
42/// Responsibilities:
43/// - Provide fallible lookups over the config *model* (`try_get_subnet`,
44///   `try_get_canister`).
45/// - Provide "current context" helpers (`cfg_current_subnet`,
46///   `cfg_current_canister`) that combine `EnvOps` (who am I?) with the
47///   static configuration model.
48///
49
50pub struct ConfigOps;
51
52impl ConfigOps {
53    /// Fetch a subnet configuration by type.
54    pub fn try_get_subnet(role: &SubnetRole) -> Result<SubnetConfig, Error> {
55        let cfg = Config::get();
56
57        let subnet_cfg = cfg
58            .get_subnet(role)
59            .ok_or_else(|| ConfigOpsError::SubnetNotFound(role.to_string()))?;
60
61        Ok(subnet_cfg)
62    }
63
64    /// Get a canister configuration inside a specific subnet.
65    pub fn try_get_canister(
66        subnet_role: &SubnetRole,
67        canister_role: &CanisterRole,
68    ) -> Result<CanisterConfig, Error> {
69        let subnet_cfg = Self::try_get_subnet(subnet_role)?;
70
71        let canister_cfg = subnet_cfg.get_canister(canister_role).ok_or_else(|| {
72            ConfigOpsError::CanisterNotFound(canister_role.to_string(), subnet_role.to_string())
73        })?;
74
75        Ok(canister_cfg)
76    }
77
78    /// Fetch the configuration record for the *current* subnet.
79    pub fn current_subnet() -> Result<SubnetConfig, Error> {
80        let subnet_role = EnvOps::try_get_subnet_role()?;
81
82        // delegate lookup to ConfigOps
83        let subnet_cfg = Self::try_get_subnet(&subnet_role)?;
84
85        Ok(subnet_cfg)
86    }
87
88    pub fn current_canister() -> Result<CanisterConfig, Error> {
89        let subnet_role = EnvOps::try_get_subnet_role()?;
90        let canister_role = EnvOps::try_get_canister_role()?;
91
92        // delegate lookup to ConfigOps or use subnet_cfg (either is fine)
93        let canister_cfg = Self::try_get_canister(&subnet_role, &canister_role)?;
94
95        Ok(canister_cfg)
96    }
97
98    pub fn current_subnet_canister(canister_role: &CanisterRole) -> Result<CanisterConfig, Error> {
99        let subnet_role = EnvOps::try_get_subnet_role()?;
100
101        // delegate lookup to ConfigOps or use subnet_cfg (either is fine)
102        let canister_cfg = Self::try_get_canister(&subnet_role, canister_role)?;
103
104        Ok(canister_cfg)
105    }
106}