DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/ExtensionManagement/
NLSResolver.rs1use std::{path::PathBuf, sync::Arc};
11
12use CommonLibrary::{Effect::ApplicationRunTime::ApplicationRunTime as _, FileSystem::ReadFile::ReadFile};
13use serde_json::{Map, Value};
14
15use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
16
17pub fn ManifestContainsNLSPlaceholders(Value:&Value) -> bool {
20 match Value {
21 serde_json::Value::String(Text) => {
22 Text.len() >= 2 && Text.starts_with('%') && Text.ends_with('%') && !Text[1..Text.len() - 1].contains('%')
23 },
24
25 serde_json::Value::Array(Items) => Items.iter().any(ManifestContainsNLSPlaceholders),
26
27 serde_json::Value::Object(Object) => Object.values().any(ManifestContainsNLSPlaceholders),
28
29 _ => false,
30 }
31}
32
33pub async fn LoadNLSBundle(
39 RunTime:&Arc<ApplicationRunTime>,
40
41 ExtensionPath:&PathBuf,
42
43 PlaceholdersNeeded:bool,
44) -> Option<Map<String, Value>> {
45 let NLSPath = ExtensionPath.join("package.nls.json");
46
47 let Content = match RunTime.Run(ReadFile(NLSPath.clone())).await {
48 Ok(Bytes) => Bytes,
49
50 Err(Error) => {
51 if PlaceholdersNeeded {
52 dev_log!("nls", "[LandFix:NLS] no bundle for {} ({})", ExtensionPath.display(), Error);
53 } else {
54 dev_log!(
55 "nls",
56 "[LandFix:NLS] {} has no placeholders, no bundle needed",
57 ExtensionPath.display()
58 );
59 }
60
61 return None;
62 },
63 };
64
65 let Parsed:Value = match serde_json::from_slice(&Content) {
66 Ok(V) => V,
67
68 Err(Error) => {
69 dev_log!("nls", "warn: [LandFix:NLS] failed to parse {}: {}", NLSPath.display(), Error);
70
71 return None;
72 },
73 };
74
75 let Object = Parsed.as_object()?;
76
77 let mut Resolved = Map::with_capacity(Object.len());
78
79 for (Key, RawValue) in Object {
80 let Text = if let Some(s) = RawValue.as_str() {
81 Some(s.to_string())
82 } else if let Some(obj) = RawValue.as_object() {
83 obj.get("message").and_then(|m| m.as_str()).map(|s| s.to_string())
84 } else {
85 None
86 };
87
88 if let Some(t) = Text {
89 Resolved.insert(Key.clone(), Value::String(t));
90 }
91 }
92
93 dev_log!(
94 "nls",
95 "[LandFix:NLS] loaded {} keys for {}",
96 Resolved.len(),
97 ExtensionPath.display()
98 );
99
100 Some(Resolved)
101}
102
103pub fn ResolveNLSPlaceholdersInner(Value:&mut Value, NLS:&Map<String, Value>, Replaced:&mut u32, Unresolved:&mut u32) {
107 match Value {
108 serde_json::Value::String(Text) => {
109 if Text.len() >= 2 && Text.starts_with('%') && Text.ends_with('%') {
110 let Key = &Text[1..Text.len() - 1];
111
112 if !Key.is_empty() && !Key.contains('%') {
113 if let Some(Replacement) = NLS.get(Key).and_then(|v| v.as_str()) {
114 *Text = Replacement.to_string();
115 *Replaced += 1;
116 } else {
117 *Unresolved += 1;
118 }
119 }
120 }
121 },
122
123 serde_json::Value::Array(Items) => {
124 for Item in Items {
125 ResolveNLSPlaceholdersInner(Item, NLS, Replaced, Unresolved);
126 }
127 },
128
129 serde_json::Value::Object(Map) => {
130 for (_, FieldValue) in Map {
131 ResolveNLSPlaceholdersInner(FieldValue, NLS, Replaced, Unresolved);
132 }
133 },
134
135 _ => {},
136 }
137}