1use crate::{
2 Error, ThisError,
3 config::{
4 Config, ConfigModel,
5 schema::{CanisterConfig, LogConfig, ScalingConfig, SubnetConfig},
6 },
7 ids::{CanisterRole, SubnetRole},
8 ops::{OpsError, runtime::env::EnvOps},
9};
10use candid::Principal;
11use std::sync::Arc;
12
13#[derive(Debug, ThisError)]
18pub enum ConfigOpsError {
19 #[error("subnet {0} not found in configuration")]
20 SubnetNotFound(String),
21
22 #[error("canister {0} not defined in subnet {1}")]
23 CanisterNotFound(String, String),
24}
25
26impl From<ConfigOpsError> for Error {
27 fn from(err: ConfigOpsError) -> Self {
28 OpsError::from(err).into()
29 }
30}
31
32pub struct ConfigOps;
44
45impl ConfigOps {
46 pub fn export_toml() -> Result<String, Error> {
52 Config::to_toml()
53 }
54
55 pub fn try_get_subnet(role: &SubnetRole) -> Result<SubnetConfig, Error> {
57 let cfg = Config::get()?;
58
59 cfg.get_subnet(role)
60 .ok_or_else(|| ConfigOpsError::SubnetNotFound(role.to_string()).into())
61 }
62
63 pub fn try_get_canister(
65 subnet_role: &SubnetRole,
66 canister_role: &CanisterRole,
67 ) -> Result<CanisterConfig, Error> {
68 let subnet_cfg = Self::try_get_subnet(subnet_role)?;
69
70 subnet_cfg.get_canister(canister_role).ok_or_else(|| {
71 ConfigOpsError::CanisterNotFound(canister_role.to_string(), subnet_role.to_string())
72 .into()
73 })
74 }
75
76 pub fn get() -> Result<Arc<ConfigModel>, Error> {
81 Config::get()
82 }
83
84 pub fn controllers() -> Result<Vec<Principal>, Error> {
85 Ok(Config::get()?.controllers.clone())
86 }
87
88 pub fn log_config() -> Result<LogConfig, Error> {
89 Ok(Config::get()?.log.clone())
90 }
91
92 pub fn current_subnet() -> Result<SubnetConfig, Error> {
94 let subnet_role = EnvOps::subnet_role()?;
95
96 Self::try_get_subnet(&subnet_role)
97 }
98
99 pub fn current_canister() -> Result<CanisterConfig, Error> {
101 let subnet_role = EnvOps::subnet_role()?;
102 let canister_role = EnvOps::canister_role()?;
103
104 Self::try_get_canister(&subnet_role, &canister_role)
105 }
106
107 pub fn current_scaling_config() -> Result<Option<ScalingConfig>, Error> {
109 Ok(Self::current_canister()?.scaling)
110 }
111
112 pub fn current_subnet_canister(canister_role: &CanisterRole) -> Result<CanisterConfig, Error> {
114 let subnet_role = EnvOps::subnet_role()?;
115
116 Self::try_get_canister(&subnet_role, canister_role)
117 }
118}