sz_rust_sdk/core/
config_manager.rs

1//! Core implementation of SzConfigManager trait
2
3use crate::{
4    error::SzResult,
5    ffi_call_config_mgr,
6    traits::{SzConfig, SzConfigManager},
7    types::{ConfigId, JsonString},
8};
9use std::ptr;
10
11/// Core implementation of the SzConfigManager trait
12pub struct SzConfigManagerCore {
13    #[allow(dead_code)]
14    handle: *mut std::ffi::c_void,
15}
16
17impl SzConfigManagerCore {
18    pub fn new() -> SzResult<Self> {
19        // Instead of initializing with empty config, reuse the existing singleton's configuration
20        // This prevents conflicts when the environment is already initialized
21        match super::environment::SzEnvironmentCore::get_existing_instance() {
22            Ok(existing_env) => {
23                // Reuse the existing environment's configuration
24                Self::new_with_params(
25                    "SzRustSDK-ConfigMgr",
26                    existing_env.get_ini_params(),
27                    existing_env.get_verbose_logging(),
28                )
29            }
30            Err(e) => {
31                // Error if no environment exists - don't create fake objects
32                Err(crate::error::SzError::configuration(format!(
33                    "Cannot create config manager without initialized environment: {}",
34                    e
35                )))
36            }
37        }
38    }
39
40    pub fn new_with_params(
41        module_name: &str,
42        ini_params: &str,
43        verbose_logging: bool,
44    ) -> SzResult<Self> {
45        // Always initialize the config manager module with parameters
46        let module_name_c = crate::ffi::helpers::str_to_c_string(module_name)?;
47        let ini_params_c = crate::ffi::helpers::str_to_c_string(ini_params)?;
48        let verbose = if verbose_logging { 1 } else { 0 };
49
50        ffi_call_config_mgr!(crate::ffi::bindings::SzConfigMgr_init(
51            module_name_c.as_ptr(),
52            ini_params_c.as_ptr(),
53            verbose
54        ));
55
56        // Config manager doesn't need a handle for the new API
57        Ok(Self {
58            handle: ptr::null_mut(),
59        })
60    }
61}
62
63impl SzConfigManager for SzConfigManagerCore {
64    fn create_config(&self) -> SzResult<Box<dyn SzConfig>> {
65        // Get current environment to use its full configuration
66        match super::environment::SzEnvironmentCore::get_existing_instance() {
67            Ok(existing_env) => {
68                // Use the same parameters as the environment
69                let config_core = super::config::SzConfigCore::new_with_params(
70                    "SzRustSDK-Config",
71                    existing_env.get_ini_params(), // Full environment config
72                    existing_env.get_verbose_logging(), // Correct verbose setting
73                )?;
74                Ok(Box::new(config_core))
75            }
76            Err(e) => {
77                // Error if no environment exists - don't create fake objects
78                Err(crate::error::SzError::configuration(format!(
79                    "Cannot create config without initialized environment: {}",
80                    e
81                )))
82            }
83        }
84    }
85
86    fn create_config_from_id(&self, config_id: ConfigId) -> SzResult<Box<dyn SzConfig>> {
87        // Get the configuration definition from the config manager
88        let result = unsafe { crate::ffi::bindings::SzConfigMgr_getConfig_helper(config_id) };
89        let config_definition =
90            unsafe { crate::ffi::helpers::process_config_mgr_pointer_result(result) }?;
91
92        // Create a new config and then load the definition
93        let config_core = super::config::SzConfigCore::new_with_definition(&config_definition)?;
94        Ok(Box::new(config_core))
95    }
96
97    fn create_config_from_definition(
98        &self,
99        config_definition: &str,
100    ) -> SzResult<Box<dyn SzConfig>> {
101        let config_core = super::config::SzConfigCore::new_with_definition(config_definition)?;
102        Ok(Box::new(config_core))
103    }
104
105    fn get_config_registry(&self) -> SzResult<JsonString> {
106        let result = unsafe { crate::ffi::bindings::SzConfigMgr_getConfigRegistry_helper() };
107        unsafe { crate::ffi::helpers::process_config_mgr_pointer_result(result) }
108    }
109
110    fn get_default_config_id(&self) -> SzResult<ConfigId> {
111        let result = unsafe { crate::ffi::bindings::SzConfigMgr_getDefaultConfigID_helper() };
112        crate::ffi::helpers::process_config_mgr_long_result(result)
113    }
114
115    fn register_config(
116        &self,
117        config_definition: &str,
118        config_comment: Option<&str>,
119    ) -> SzResult<ConfigId> {
120        let config_def_c = crate::ffi::helpers::str_to_c_string(config_definition)?;
121        let comment_c = crate::ffi::helpers::str_to_c_string(config_comment.unwrap_or(""))?;
122
123        let result = unsafe {
124            crate::ffi::bindings::SzConfigMgr_registerConfig_helper(
125                config_def_c.as_ptr(),
126                comment_c.as_ptr(),
127            )
128        };
129
130        crate::ffi::helpers::process_config_mgr_long_result(result)
131    }
132
133    fn replace_default_config_id(
134        &self,
135        current_default_config_id: ConfigId,
136        new_default_config_id: ConfigId,
137    ) -> SzResult<()> {
138        ffi_call_config_mgr!(crate::ffi::bindings::SzConfigMgr_replaceDefaultConfigID(
139            current_default_config_id,
140            new_default_config_id
141        ));
142        Ok(())
143    }
144
145    fn set_default_config(
146        &self,
147        config_definition: &str,
148        config_comment: Option<&str>,
149    ) -> SzResult<ConfigId> {
150        let config_id = self.register_config(config_definition, config_comment)?;
151        self.set_default_config_id(config_id)?;
152        Ok(config_id)
153    }
154
155    fn set_default_config_id(&self, config_id: ConfigId) -> SzResult<()> {
156        ffi_call_config_mgr!(crate::ffi::bindings::SzConfigMgr_setDefaultConfigID(
157            config_id
158        ));
159        Ok(())
160    }
161}
162
163impl Drop for SzConfigManagerCore {
164    fn drop(&mut self) {
165        // NOTE: SzConfigMgr_destroy() should only be called when the entire process is shutting down
166        // or when we're certain no other SzConfigManager instances will be needed.
167        // For now, we only clear exceptions.
168        // Module destruction should be handled by a singleton manager or at process exit.
169        unsafe {
170            crate::ffi::bindings::SzConfigMgr_clearLastException();
171        }
172    }
173}