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        model::memory::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(ty: &SubnetRole) -> Result<SubnetConfig, Error> {
55        let subnet_cfg = Config::get()
56            .get_subnet(ty)
57            .ok_or_else(|| ConfigOpsError::SubnetNotFound(ty.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_type: &SubnetRole,
65        canister_type: &CanisterRole,
66    ) -> Result<CanisterConfig, Error> {
67        let subnet_cfg = Self::try_get_subnet(subnet_type)?;
68
69        let canister_cfg = subnet_cfg.get_canister(canister_type).ok_or_else(|| {
70            ConfigOpsError::CanisterNotFound(canister_type.to_string(), subnet_type.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_type = EnvOps::try_get_subnet_type()?;
79
80        // delegate lookup to ConfigOps
81        let subnet_cfg = Self::try_get_subnet(&subnet_type)?;
82
83        Ok(subnet_cfg)
84    }
85
86    pub fn current_canister() -> Result<CanisterConfig, Error> {
87        let subnet_type = EnvOps::try_get_subnet_type()?;
88        let canister_type = EnvOps::try_get_canister_type()?;
89
90        // delegate lookup to ConfigOps or use subnet_cfg (either is fine)
91        let canister_cfg = Self::try_get_canister(&subnet_type, &canister_type)?;
92
93        Ok(canister_cfg)
94    }
95
96    pub fn current_subnet_canister(canister_type: &CanisterRole) -> Result<CanisterConfig, Error> {
97        let subnet_type = EnvOps::try_get_subnet_type()?;
98
99        // delegate lookup to ConfigOps or use subnet_cfg (either is fine)
100        let canister_cfg = Self::try_get_canister(&subnet_type, canister_type)?;
101
102        Ok(canister_cfg)
103    }
104}