release/0.5.0 #15

Merged
nvrl merged 16 commits from release/0.5.0 into main 2026-03-18 22:50:11 +01:00
Showing only changes of commit a2ec8660c7 - Show all commits

View File

@@ -119,38 +119,99 @@ fn xml_to_json(content: &str) -> anyhow::Result<Value> {
} }
fn json_to_xml(value: &Value) -> String { fn json_to_xml(value: &Value) -> String {
use quick_xml::Writer;
use quick_xml::events::{Event, BytesStart, BytesEnd, BytesText};
let mut writer = Writer::new_with_indent(Vec::new(), b' ', 4);
fn write_recursive(writer: &mut Writer<Vec<u8>>, value: &Value, key_name: Option<&str>) {
if let Some(k) = key_name {
if k == "$text" {
if let Some(s) = value.as_str() {
writer.write_event(Event::Text(BytesText::new(s))).unwrap();
}
return;
}
}
match value { match value {
Value::Object(map) => { Value::Object(map) => {
let mut s = String::new(); if let Some(k) = key_name {
writer.write_event(Event::Start(BytesStart::new(k))).unwrap();
}
for (k, v) in map { for (k, v) in map {
if k == "$text" { if let Some(arr) = v.as_array() {
s.push_str(v.as_str().unwrap_or(""));
} else if let Some(arr) = v.as_array() {
for item in arr { for item in arr {
s.push_str(&format!("<{}>", k)); write_recursive(writer, item, Some(k));
s.push_str(&json_to_xml(item));
s.push_str(&format!("</{}>", k));
} }
} else { } else {
s.push_str(&format!("<{}>", k)); write_recursive(writer, v, Some(k));
s.push_str(&json_to_xml(v));
s.push_str(&format!("</{}>", k));
} }
} }
s if let Some(k) = key_name {
writer.write_event(Event::End(BytesEnd::new(k))).unwrap();
}
} }
Value::Array(arr) => { Value::Array(arr) => {
let mut s = String::new();
for v in arr { for v in arr {
s.push_str(&json_to_xml(v)); write_recursive(writer, v, key_name);
} }
s
} }
Value::String(v) => v.clone(), Value::String(s) => {
Value::Number(v) => v.to_string(), if let Some(k) = key_name {
Value::Bool(v) => v.to_string(), writer.write_event(Event::Start(BytesStart::new(k))).unwrap();
Value::Null => "".to_string(),
} }
writer.write_event(Event::Text(BytesText::new(s))).unwrap();
if let Some(k) = key_name {
writer.write_event(Event::End(BytesEnd::new(k))).unwrap();
}
}
Value::Number(n) => {
if let Some(k) = key_name {
writer.write_event(Event::Start(BytesStart::new(k))).unwrap();
}
writer.write_event(Event::Text(BytesText::new(&n.to_string()))).unwrap();
if let Some(k) = key_name {
writer.write_event(Event::End(BytesEnd::new(k))).unwrap();
}
}
Value::Bool(b) => {
if let Some(k) = key_name {
writer.write_event(Event::Start(BytesStart::new(k))).unwrap();
}
writer.write_event(Event::Text(BytesText::new(&b.to_string()))).unwrap();
if let Some(k) = key_name {
writer.write_event(Event::End(BytesEnd::new(k))).unwrap();
}
}
Value::Null => {
if let Some(k) = key_name {
writer.write_event(Event::Empty(BytesStart::new(k))).unwrap();
}
}
}
}
if value.is_object() {
for (k, v) in value.as_object().unwrap() {
if let Some(arr) = v.as_array() {
for item in arr {
write_recursive(&mut writer, item, Some(k));
}
} else {
write_recursive(&mut writer, v, Some(k));
}
}
} else {
write_recursive(&mut writer, value, None);
}
// Quick-XML adds a trailing newline occasionally, or we might need one
let mut out = String::from_utf8(writer.into_inner()).unwrap();
if !out.ends_with('\n') {
out.push('\n');
}
out
} }
fn flatten(value: &Value, current_path: Vec<PathSegment>, key_name: Option<String>, depth: usize, vars: &mut Vec<ConfigItem>) { fn flatten(value: &Value, current_path: Vec<PathSegment>, key_name: Option<String>, depth: usize, vars: &mut Vec<ConfigItem>) {