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 subnet_cfg = Config::get()
56            .get_subnet(role)
57            .ok_or_else(|| ConfigOpsError::SubnetNotFound(role.to_string()))?;
58
59        Ok(subnet_cfg)
60    }
61
62    /// Get a canister configuration inside a specific subnet.
63    pub fn try_get_canister(
64        subnet_role: &SubnetRole,
65        canister_role: &CanisterRole,
66    ) -> Result<CanisterConfig, Error> {
67        let subnet_cfg = Self::try_get_subnet(subnet_role)?;
68
69        let canister_cfg = subnet_cfg.get_canister(canister_role).ok_or_else(|| {
70            ConfigOpsError::CanisterNotFound(canister_role.to_string(), subnet_role.to_string())
71        })?;
72
73        Ok(canister_cfg)
74    }
75
76    /// Fetch the configuration record for the *current* subnet.
77    pub fn current_subnet() -> Result<SubnetConfig, Error> {
78        let subnet_role = EnvOps::try_get_subnet_role()?;
79
80        // delegate lookup to ConfigOps
81        let subnet_cfg = Self::try_get_subnet(&subnet_role)?;
82
83        Ok(subnet_cfg)
84    }
85
86    pub fn current_canister() -> Result<CanisterConfig, Error> {
87        let subnet_role = EnvOps::try_get_subnet_role()?;
88        let canister_role = EnvOps::try_get_canister_role()?;
89
90        // delegate lookup to ConfigOps or use subnet_cfg (either is fine)
91        let canister_cfg = Self::try_get_canister(&subnet_role, &canister_role)?;
92
93        Ok(canister_cfg)
94    }
95
96    pub fn current_subnet_canister(canister_role: &CanisterRole) -> Result<CanisterConfig, Error> {
97        let subnet_role = EnvOps::try_get_subnet_role()?;
98
99        // delegate lookup to ConfigOps or use subnet_cfg (either is fine)
100        let canister_cfg = Self::try_get_canister(&subnet_role, canister_role)?;
101
102        Ok(canister_cfg)
103    }
104}