devalang_core/config/
loader.rs

1use crate::config::driver::{ProjectConfig, ProjectConfigBankEntry, ProjectConfigBankMetadata};
2use std::{fs, path::Path};
3
4pub fn load_config(path: Option<&Path>) -> Option<ProjectConfig> {
5    let config_path = path.unwrap_or_else(|| Path::new(".devalang"));
6
7    if config_path.exists() {
8        let content = fs::read_to_string(config_path).ok()?;
9        toml::from_str(&content).ok()
10    } else {
11        None
12    }
13}
14
15pub fn update_bank_version_in_config(
16    config: &mut ProjectConfig,
17    dependency: &str,
18    new_version: &str,
19) {
20    if config.banks.is_none() {
21        println!("No banks configured.");
22        return;
23    }
24
25    let banks = config.banks.as_mut().unwrap();
26
27    if let Some(bank) = banks.iter_mut().find(|b| b.path.contains(dependency)) {
28        bank.version = Some(new_version.to_string());
29
30        if let Err(e) = config.write(config) {
31            eprintln!("❌ Failed to write config: {}", e);
32        } else {
33            println!(
34                "✅ Bank '{}' updated to version '{}'",
35                dependency, new_version
36            );
37        }
38    } else {
39        println!("Bank '{}' not found in config", dependency);
40    }
41}
42
43pub fn remove_bank_from_config(config: &mut ProjectConfig, dependency: &str) {
44    if config.banks.is_none() {
45        println!("No banks configured.");
46        return;
47    }
48
49    let banks = config.banks.as_mut().unwrap();
50
51    if let Some(index) = banks.iter().position(|b| b.path.contains(dependency)) {
52        banks.remove(index);
53
54        if let Err(e) = config.write(config) {
55            eprintln!("❌ Failed to write config: {}", e);
56        } else {
57            println!("✅ Bank '{}' removed from config", dependency);
58        }
59    } else {
60        println!("Bank '{}' not found in config", dependency);
61    }
62}
63
64pub fn add_plugin_to_config(config: &mut ProjectConfig, real_path: &Path, dependency: &str) {
65    if config.plugins.is_none() {
66        config.plugins = Some(Vec::new());
67    }
68
69    let plugins = config.plugins.as_mut().unwrap();
70
71    let exists = plugins.iter().any(|p| p.path == dependency);
72    if exists {
73        println!("Plugin '{}' already in config", dependency);
74        return;
75    }
76
77    let metadata_path = Path::new(real_path).join("plugin.toml");
78
79    if !metadata_path.exists() {
80        eprintln!(
81            "❌ Plugin metadata file '{}' does not exist",
82            metadata_path.display()
83        );
84        return;
85    }
86
87    let metadata_content =
88        std::fs::read_to_string(&metadata_path).expect("Failed to read plugin metadata file");
89
90    let metadata: std::collections::HashMap<String, String> =
91        toml::from_str(&metadata_content).expect("Failed to parse plugin metadata file");
92
93    let plugin_entry = crate::config::driver::PluginEntry {
94        path: dependency.to_string(),
95        version: metadata
96            .get("version")
97            .cloned()
98            .unwrap_or_else(|| "0.0.1".to_string()),
99        author: metadata
100            .get("author")
101            .cloned()
102            .unwrap_or_else(|| "unknown".to_string()),
103        access: metadata
104            .get("access")
105            .cloned()
106            .unwrap_or_else(|| "public".to_string()),
107    };
108
109    plugins.push(plugin_entry);
110
111    if let Err(e) = config.write(config) {
112        eprintln!("❌ Failed to write config: {}", e);
113    } else {
114        println!("✅ Plugin '{}' added to config", dependency);
115    }
116}
117
118pub fn add_bank_to_config(config: &mut ProjectConfig, real_path: &Path, dependency: &str) {
119    if config.banks.is_none() {
120        config.banks = Some(Vec::new());
121    }
122
123    let banks = config.banks.as_mut().unwrap();
124
125    let exists = banks.iter().any(|b| b.path == dependency);
126    if exists {
127        println!("Bank '{}' already in config", dependency);
128        return;
129    }
130
131    let metadata_path = Path::new(real_path).join("bank.toml");
132
133    if !metadata_path.exists() {
134        eprintln!(
135            "❌ Bank metadata file '{}' does not exist",
136            metadata_path.display()
137        );
138        return;
139    }
140
141    let metadata_content =
142        fs::read_to_string(&metadata_path).expect("Failed to read bank metadata file");
143
144    let metadata: ProjectConfigBankMetadata =
145        toml::from_str(&metadata_content).expect("Failed to parse bank metadata file");
146
147    let bank_to_insert = ProjectConfigBankEntry {
148        path: dependency.to_string(),
149        version: Some(
150            metadata
151                .bank
152                .get("version")
153                .cloned()
154                .unwrap_or_else(|| "0.0.1".to_string()),
155        ),
156    };
157
158    banks.push(bank_to_insert);
159
160    if let Err(e) = config.write(config) {
161        eprintln!("❌ Failed to write config: {}", e);
162    } else {
163        println!("✅ Bank '{}' added to config", dependency);
164    }
165}