1use std::{collections::HashMap, path::Path};
6
7use super::{LocalizationBundle, NLSConfig};
8
9pub struct NLSBundle {
11 _config:NLSConfig,
12
13 bundles:HashMap<String, LocalizationBundle>,
15}
16
17impl NLSBundle {
18 pub fn new(config:NLSConfig) -> Self {
19 let mut bundles = HashMap::new();
20
21 for lang in &config.languages {
23 bundles.insert(lang.clone(), LocalizationBundle::new(lang));
24 }
25
26 Self { _config:config, bundles }
27 }
28
29 pub fn add_entry(&mut self, language:&str, key:impl Into<String>, value:impl Into<String>) {
31 if let Some(bundle) = self.bundles.get_mut(language) {
32 bundle.add_entry(key, value);
33 }
34 }
35
36 pub fn add_entries(&mut self, language:&str, entries:&HashMap<String, String>) {
38 if let Some(bundle) = self.bundles.get_mut(language) {
39 for (key, value) in entries {
40 bundle.add_entry(key.clone(), value.clone());
41 }
42
43 bundle.compute_hash();
44 }
45 }
46
47 pub fn generate(&self, output_dir:&Path) -> std::io::Result<()> {
49 use std::fs;
50
51 fs::create_dir_all(output_dir)?;
53
54 for (lang, bundle) in &self.bundles {
55 let filename = format!("{}.json", lang);
56
57 let path = output_dir.join(&filename);
58
59 let json =
60 serde_json::to_string_pretty(bundle).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
61
62 fs::write(path, json)?;
63 }
64
65 Ok(())
66 }
67
68 pub fn get_bundle(&self, language:&str) -> Option<&LocalizationBundle> { self.bundles.get(language) }
70
71 pub fn all_bundles(&self) -> &HashMap<String, LocalizationBundle> { &self.bundles }
73
74 pub fn load_bundle(language:&str, path:&Path) -> std::io::Result<LocalizationBundle> {
76 let content = std::fs::read_to_string(path)?;
77
78 let bundle:LocalizationBundle =
79 serde_json::from_str(&content).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
80
81 if bundle.language != language {
83 return Err(std::io::Error::new(
84 std::io::ErrorKind::InvalidData,
85 format!("Language mismatch: expected {}, got {}", language, bundle.language),
86 ));
87 }
88
89 Ok(bundle)
90 }
91
92 pub fn to_hashmap(&self, language:&str) -> HashMap<String, String> {
94 let mut map = HashMap::new();
95
96 if let Some(bundle) = self.bundles.get(language) {
97 for entry in &bundle.entries {
98 map.insert(entry.key.clone(), entry.value.clone());
99 }
100 }
101
102 map
103 }
104}
105
106pub fn generate_vscode_bundle(entries:&HashMap<String, String>, language:&str) -> LocalizationBundle {
108 let mut bundle = LocalizationBundle::new(language);
109
110 for (key, value) in entries {
111 bundle.add_entry(key, value);
112 }
113
114 bundle.compute_hash();
115
116 bundle
117}
118
119pub fn format_metadata(bundle:&LocalizationBundle) -> serde_json::Value {
121 let mut metadata = serde_json::Map::new();
122
123 for entry in &bundle.entries {
124 let mut item = serde_json::Map::new();
125
126 item.insert("value".to_string(), serde_json::Value::String(entry.value.clone()));
127
128 if let Some(comment) = &entry.comment {
129 item.insert("comment".to_string(), serde_json::Value::String(comment.clone()));
130 }
131
132 metadata.insert(entry.key.clone(), serde_json::Value::Object(item));
133 }
134
135 serde_json::Value::Object(metadata)
136}
137
138#[cfg(test)]
139mod tests {
140
141 use super::*;
142
143 #[test]
144 fn test_bundle_creation() {
145 let config = NLSConfig { languages:vec!["en".to_string(), "de".to_string()], ..Default::default() };
146
147 let bundle = NLSBundle::new(config);
148
149 assert!(bundle.get_bundle("en").is_some());
150
151 assert!(bundle.get_bundle("de").is_some());
152 }
153
154 #[test]
155 fn test_add_entry() {
156 let config = NLSConfig { languages:vec!["en".to_string()], ..Default::default() };
157
158 let mut bundle = NLSBundle::new(config);
159
160 bundle.add_entry("en", "hello", "Hello World");
161
162 let en_bundle = bundle.get_bundle("en").unwrap();
163
164 assert_eq!(en_bundle.entries.len(), 1);
165
166 assert_eq!(en_bundle.entries[0].key, "hello");
167 }
168
169 #[test]
170 fn test_to_hashmap() {
171 let config = NLSConfig { languages:vec!["en".to_string()], ..Default::default() };
172
173 let mut bundle = NLSBundle::new(config);
174
175 bundle.add_entry("en", "hello", "Hello World");
176
177 let map = bundle.to_hashmap("en");
178
179 assert_eq!(map.get("hello"), Some(&"Hello World".to_string()));
180 }
181}