Skip to main content

Library/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
15	/// Whether to preserve the localize call structure
16	preserve_calls:bool,
17
18	/// Regex patterns for localize calls
19	localize_pattern:Regex,
20
21	_localize2_pattern:Regex,
22}
23
24impl NLSReplacer {
25	pub fn new(bundle:HashMap<String, String>) -> Self {
26		Self {
27			bundle,
28
29			preserve_calls:false,
30
31			localize_pattern:Regex::new(r#"(?:nls\.)?localize\s*\(\s*['"]([^'"]+)['"]"#).unwrap(),
32
33			_localize2_pattern:Regex::new(r#"(?:nls\.)?localize2\s*\(\s*['"]([^'"]+)['"]"#).unwrap(),
34		}
35	}
36
37	pub fn with_preserve_calls(mut self, preserve:bool) -> Self {
38		self.preserve_calls = preserve;
39
40		self
41	}
42
43	/// Replace NLS keys in source code
44	pub fn replace(&self, source:&str) -> String {
45		let mut result = source.to_string();
46
47		// Replace localize calls
48		if let Some(caps) = self.localize_pattern.captures(&result) {
49			if let Some(key) = caps.get(1) {
50				let key_str = key.as_str();
51
52				if let Some(value) = self.bundle.get(key_str) {
53					let pattern = format!(r#"nls.localize\s*\(\s*['"]{}.*?\)"#, regex::escape(key_str));
54
55					let re = Regex::new(&pattern).unwrap();
56
57					if self.preserve_calls {
58						// Keep the call but with replacement
59						result = re
60							.replace_all(&result, format!("/* localize('{}') */ '{}'", key_str, value))
61							.to_string();
62					} else {
63						// Replace with just the string value
64						result = re.replace_all(&result, format!("'{}'", value)).to_string();
65					}
66				}
67			}
68		}
69
70		result
71	}
72}
73
74/// Replace NLS keys in source code with translations
75pub fn replace_nls_keys(source:&str, bundle:&HashMap<String, String>) -> String {
76	let replacer = NLSReplacer::new(bundle.clone());
77
78	replacer.replace(source)
79}
80
81#[cfg(test)]
82mod tests {
83
84	use super::*;
85
86	#[test]
87	fn test_replacer_creation() {
88		let bundle = HashMap::new();
89
90		let replacer = NLSReplacer::new(bundle);
91
92		assert!(!replacer.preserve_calls);
93	}
94
95	#[test]
96	fn test_replacer_with_preserve() {
97		let bundle = HashMap::new();
98
99		let replacer = NLSReplacer::new(bundle).with_preserve_calls(true);
100
101		assert!(replacer.preserve_calls);
102	}
103
104	#[test]
105	fn test_replace_keys() {
106		let mut bundle = HashMap::new();
107
108		bundle.insert("hello".to_string(), "Hello World".to_string());
109
110		let source = r#"nls.localize('hello', 'default')"#;
111
112		let result = replace_nls_keys(source, &bundle);
113
114		assert!(result.contains("Hello World"));
115	}
116}