Skip to main content

Rest/Fn/NLS/
replace.rs

1//! NLS key replacement transform
2//!
3//! Replaces NLS keys with actual localized strings at build time.
4//! This is used when inlining translations into the output.
5
6use std::collections::HashMap;
7
8use regex::Regex;
9
10/// Replaces NLS localization calls with actual string values
11pub struct NLSReplacer {
12	/// The localization bundle to use for replacements
13	bundle:HashMap<String, String>,
14	/// Whether to preserve the localize call structure
15	preserve_calls:bool,
16	/// Regex patterns for localize calls
17	localize_pattern:Regex,
18	_localize2_pattern:Regex,
19}
20
21impl NLSReplacer {
22	pub fn new(bundle:HashMap<String, String>) -> Self {
23		Self {
24			bundle,
25			preserve_calls:false,
26			localize_pattern:Regex::new(r#"(?:nls\.)?localize\s*\(\s*['"]([^'"]+)['"]"#).unwrap(),
27			_localize2_pattern:Regex::new(r#"(?:nls\.)?localize2\s*\(\s*['"]([^'"]+)['"]"#).unwrap(),
28		}
29	}
30
31	pub fn with_preserve_calls(mut self, preserve:bool) -> Self {
32		self.preserve_calls = preserve;
33		self
34	}
35
36	/// Replace NLS keys in source code
37	pub fn replace(&self, source:&str) -> String {
38		let mut result = source.to_string();
39
40		// Replace localize calls
41		if let Some(caps) = self.localize_pattern.captures(&result) {
42			if let Some(key) = caps.get(1) {
43				let key_str = key.as_str();
44				if let Some(value) = self.bundle.get(key_str) {
45					let pattern = format!(r#"nls.localize\s*\(\s*['"]{}.*?\)"#, regex::escape(key_str));
46					let re = Regex::new(&pattern).unwrap();
47					if self.preserve_calls {
48						// Keep the call but with replacement
49						result = re
50							.replace_all(&result, format!("/* localize('{}') */ '{}'", key_str, value))
51							.to_string();
52					} else {
53						// Replace with just the string value
54						result = re.replace_all(&result, format!("'{}'", value)).to_string();
55					}
56				}
57			}
58		}
59
60		result
61	}
62}
63
64/// Replace NLS keys in source code with translations
65pub fn replace_nls_keys(source:&str, bundle:&HashMap<String, String>) -> String {
66	let replacer = NLSReplacer::new(bundle.clone());
67	replacer.replace(source)
68}
69
70#[cfg(test)]
71mod tests {
72	use super::*;
73
74	#[test]
75	fn test_replacer_creation() {
76		let bundle = HashMap::new();
77		let replacer = NLSReplacer::new(bundle);
78		assert!(!replacer.preserve_calls);
79	}
80
81	#[test]
82	fn test_replacer_with_preserve() {
83		let bundle = HashMap::new();
84		let replacer = NLSReplacer::new(bundle).with_preserve_calls(true);
85		assert!(replacer.preserve_calls);
86	}
87
88	#[test]
89	fn test_replace_keys() {
90		let mut bundle = HashMap::new();
91		bundle.insert("hello".to_string(), "Hello World".to_string());
92
93		let source = r#"nls.localize('hello', 'default')"#;
94		let result = replace_nls_keys(source, &bundle);
95
96		assert!(result.contains("Hello World"));
97	}
98}