Skip to main content

gaia_assembler/config/
mod.rs

1//! 配置管理模块
2//!
3//! 本模块负责加载和管理Gaia汇编器的配置,包括平台映射、适配器配置等。
4//! 支持从TOML配置文件动态加载配置信息。
5
6use gaia_types::{
7    helpers::{AbiCompatible, ApiCompatible, Architecture, CompilationTarget},
8    GaiaError, Result,
9};
10use serde::{Deserialize, Serialize};
11use std::{collections::HashMap, fs, path::Path};
12
13/// 函数映射配置
14///
15/// 定义了通用函数名到平台特定函数名的映射关系
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct FunctionMapping {
18    /// 通用函数名
19    pub common_name: String,
20    /// 平台特定映射
21    pub platform_mappings: HashMap<String, String>,
22    /// 函数描述
23    pub description: Option<String>,
24}
25
26/// 平台配置
27///
28/// 包含特定平台的配置信息
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct PlatformConfig {
31    /// 编译目标
32    pub target: CompilationTarget,
33    /// 平台描述
34    pub description: Option<String>,
35    /// 支持的架构
36    pub supported_architectures: Vec<String>,
37    /// 默认文件扩展名
38    pub default_extension: String,
39    /// 平台特定参数
40    pub parameters: HashMap<String, String>,
41}
42
43/// 适配器配置
44///
45/// 包含适配器的配置信息
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct AdapterConfigEntry {
48    /// 适配器名称
49    pub name: String,
50    /// 适配器类型 (export/import)
51    pub adapter_type: String,
52    /// 编译目标
53    pub compilation_target: CompilationTarget,
54    /// 是否启用
55    pub enabled: bool,
56    /// 适配器参数
57    pub parameters: HashMap<String, String>,
58}
59
60/// 全局配置
61///
62/// 包含全局设置参数
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct GlobalConfig {
65    /// 默认输出目录
66    pub default_output_dir: String,
67    /// 是否启用调试模式
68    pub debug_mode: bool,
69    /// 全局参数
70    pub parameters: HashMap<String, String>,
71}
72
73impl Default for GlobalConfig {
74    fn default() -> Self {
75        Self { default_output_dir: "./target".to_string(), debug_mode: false, parameters: HashMap::new() }
76    }
77}
78
79pub struct GaiaConfig {
80    /// static part when load
81    pub setting: GaiaSettings,
82
83    pub target: CompilationTarget,
84}
85
86impl Default for GaiaConfig {
87    fn default() -> Self {
88        Self {
89            setting: GaiaSettings::default(),
90            target: CompilationTarget {
91                build: Architecture::Unknown,
92                host: AbiCompatible::Unknown,
93                target: ApiCompatible::Unknown,
94            },
95        }
96    }
97}
98
99/// Gaia汇编器主配置
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct GaiaSettings {
102    /// 配置版本
103    pub version: String,
104    /// 全局设置
105    pub global: GlobalConfig,
106    /// 平台配置映射
107    #[serde(with = "target_map_serde")]
108    pub platforms: HashMap<CompilationTarget, PlatformConfig>,
109    /// 函数映射列表
110    pub function_mappings: Vec<FunctionMapping>,
111    /// 适配器配置列表
112    pub adapters: Vec<AdapterConfigEntry>,
113}
114
115mod target_map_serde {
116    use super::*;
117    use serde::{Deserializer, Serializer};
118    use std::str::FromStr;
119
120    pub fn serialize<S>(map: &HashMap<CompilationTarget, PlatformConfig>, serializer: S) -> std::result::Result<S::Ok, S::Error>
121    where
122        S: Serializer,
123    {
124        let string_map: HashMap<String, PlatformConfig> = map.iter().map(|(k, v)| (k.to_string(), v.clone())).collect();
125        string_map.serialize(serializer)
126    }
127
128    pub fn deserialize<'de, D>(deserializer: D) -> std::result::Result<HashMap<CompilationTarget, PlatformConfig>, D::Error>
129    where
130        D: Deserializer<'de>,
131    {
132        let string_map: HashMap<String, PlatformConfig> = HashMap::deserialize(deserializer)?;
133        let mut map = HashMap::new();
134        for (k, v) in string_map {
135            // NOTE: This assumes CompilationTarget::from_str is implemented or we have a way to parse it.
136            // CompilationTarget has Display, but does it have FromStr?
137            // Let's check gaia_types.
138            let target = parse_target(&k).map_err(serde::de::Error::custom)?;
139            map.insert(target, v);
140        }
141        Ok(map)
142    }
143
144    fn parse_target(s: &str) -> std::result::Result<CompilationTarget, String> {
145        let parts: Vec<&str> = s.split('-').collect();
146        if parts.len() != 3 {
147            return Err(format!("Invalid compilation target string: {}", s));
148        }
149
150        let build = Architecture::from_str(parts[0])?;
151        let host = AbiCompatible::from_str(parts[1])?;
152        let target = ApiCompatible::from_str(parts[2])?;
153
154        Ok(CompilationTarget { build, host, target })
155    }
156}
157
158impl Default for GaiaSettings {
159    fn default() -> Self {
160        Self {
161            version: "1.0.0".to_string(),
162            global: GlobalConfig::default(),
163            platforms: {
164                let mut platforms = HashMap::new();
165                let x64_target = CompilationTarget {
166                    build: Architecture::X86_64,
167                    host: AbiCompatible::PE,
168                    target: ApiCompatible::MicrosoftVisualC,
169                };
170                platforms.insert(
171                    x64_target.clone(),
172                    PlatformConfig {
173                        target: x64_target,
174                        description: Some("Windows x64 Native".to_string()),
175                        supported_architectures: vec!["x86_64".to_string()],
176                        default_extension: ".exe".to_string(),
177                        parameters: HashMap::new(),
178                    },
179                );
180
181                let clr_target = CompilationTarget {
182                    build: Architecture::CLR,
183                    host: AbiCompatible::PE,
184                    target: ApiCompatible::ClrRuntime(4),
185                };
186                platforms.insert(
187                    clr_target.clone(),
188                    PlatformConfig {
189                        target: clr_target,
190                        description: Some(".NET CLR v4.0".to_string()),
191                        supported_architectures: vec!["msil".to_string()],
192                        default_extension: ".exe".to_string(),
193                        parameters: HashMap::new(),
194                    },
195                );
196                platforms
197            },
198            function_mappings: vec![
199                FunctionMapping {
200                    common_name: "__builtin_print".to_string(),
201                    platform_mappings: [
202                        ("PE".to_string(), "printf".to_string()),
203                        ("IL".to_string(), "System.Console.WriteLine".to_string()),
204                        ("JVM".to_string(), "java.lang.System.out.println".to_string()),
205                        ("WASI".to_string(), "fd_write".to_string()),
206                    ]
207                    .into_iter()
208                    .collect(),
209                    description: Some("标准输出函数".to_string()),
210                },
211                FunctionMapping {
212                    common_name: "malloc".to_string(),
213                    platform_mappings: [
214                        ("PE".to_string(), "malloc".to_string()),
215                        ("IL".to_string(), "System.Runtime.InteropServices.Marshal.AllocHGlobal".to_string()),
216                        ("JVM".to_string(), "java.nio.ByteBuffer.allocate".to_string()),
217                        ("WASI".to_string(), "memory.grow".to_string()),
218                    ]
219                    .into_iter()
220                    .collect(),
221                    description: Some("内存分配函数".to_string()),
222                },
223                FunctionMapping {
224                    common_name: "free".to_string(),
225                    platform_mappings: [
226                        ("PE".to_string(), "free".to_string()),
227                        ("IL".to_string(), "System.Runtime.InteropServices.Marshal.FreeHGlobal".to_string()),
228                        ("JVM".to_string(), "System.gc".to_string()),
229                        ("WASI".to_string(), "memory.shrink".to_string()),
230                    ]
231                    .into_iter()
232                    .collect(),
233                    description: Some("内存释放函数".to_string()),
234                },
235            ],
236            adapters: vec![],
237        }
238    }
239}
240
241/// 配置管理器
242///
243/// 负责加载、保存和管理配置信息
244pub struct ConfigManager {
245    /// 当前配置
246    config: GaiaSettings,
247    /// 配置文件路径
248    config_path: Option<String>,
249}
250
251impl ConfigManager {
252    /// 创建新的配置管理器
253    pub fn new() -> Self {
254        Self { config: GaiaSettings::default(), config_path: None }
255    }
256
257    /// 从文件加载配置
258    ///
259    /// # 参数
260    /// * `path` - 配置文件路径
261    ///
262    /// # 返回值
263    /// 加载成功返回Ok(()),失败返回错误信息
264    pub fn load_from_file<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
265        let path = path.as_ref();
266        let content = fs::read_to_string(path)
267            .map_err(|e| GaiaError::config_error(Some(path.to_string_lossy()), format!("读取配置文件失败: {}", e)))?;
268
269        self.config = toml::from_str(&content)
270            .map_err(|e| GaiaError::config_error(Some(path.to_string_lossy()), format!("解析配置文件失败: {}", e)))?;
271
272        self.config_path = Some(path.to_string_lossy().to_string());
273        Ok(())
274    }
275
276    /// 保存配置到文件
277    ///
278    /// # 参数
279    /// * `path` - 配置文件路径
280    ///
281    /// # 返回值
282    /// 保存成功返回Ok(()),失败返回错误信息
283    pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()> {
284        let path = path.as_ref();
285        let content = toml::to_string_pretty(&self.config)
286            .map_err(|e| GaiaError::config_error(Some(path.to_string_lossy()), format!("序列化配置失败: {}", e)))?;
287
288        fs::write(path, content)
289            .map_err(|e| GaiaError::config_error(Some(path.to_string_lossy()), format!("写入配置文件失败: {}", e)))?;
290
291        Ok(())
292    }
293
294    /// 获取当前设置
295    pub fn settings(&self) -> &GaiaSettings {
296        &self.config
297    }
298
299    /// 获取当前设置 (兼容旧代码)
300    pub fn config(&self) -> &GaiaSettings {
301        &self.config
302    }
303
304    /// 获取全局设置
305    pub fn get_global_setting(&self, key: &str) -> Option<&str> {
306        self.config.global.parameters.get(key).map(|s| s.as_str())
307    }
308
309    /// 设置全局设置
310    pub fn set_global_setting(&mut self, key: String, value: String) {
311        self.config.global.parameters.insert(key, value);
312    }
313
314    /// 获取平台配置
315    pub fn get_platform_config(&self, target: &CompilationTarget) -> Option<&PlatformConfig> {
316        self.config.platforms.get(target)
317    }
318
319    /// 添加平台配置
320    pub fn add_platform_config(&mut self, target: CompilationTarget, config: PlatformConfig) {
321        self.config.platforms.insert(target, config);
322    }
323
324    /// 添加适配器配置
325    pub fn add_adapter_config(&mut self, config: AdapterConfigEntry) {
326        self.config.adapters.push(config);
327    }
328
329    /// 获取适配器配置
330    pub fn get_adapter_config(&self, name: &str) -> Option<&AdapterConfigEntry> {
331        self.config.adapters.iter().find(|a| a.name == name)
332    }
333
334    /// 添加函数映射
335    pub fn add_function_mapping(&mut self, mapping: FunctionMapping) {
336        self.config.function_mappings.push(mapping);
337    }
338
339    /// 获取函数映射
340    pub fn get_function_mapping(&self, common_name: &str, platform: &str) -> Option<&str> {
341        self.config
342            .function_mappings
343            .iter()
344            .find(|m| m.common_name == common_name)
345            .and_then(|m| m.platform_mappings.get(platform).map(|s| s.as_str()))
346    }
347
348    /// 验证配置
349    pub fn validate(&self) -> Result<()> {
350        Ok(())
351    }
352
353    /// 获取当前配置文件的路径
354    pub fn config_path(&self) -> Option<&str> {
355        self.config_path.as_deref()
356    }
357}