const ALIASES: &[(&str, &str)] = &[("gateway", "a2a")];
pub(crate) fn fold_legacy_sections(doc: &mut toml::Value) -> Vec<&'static str> {
let mut folded = Vec::new();
let Some(table) = doc.as_table_mut() else {
return folded;
};
for (legacy, canonical) in ALIASES {
let Some(legacy_val) = table.remove(*legacy) else {
continue;
};
folded.push(*legacy);
match table.get_mut(*canonical) {
Some(canon_val) => merge_into(canon_val, legacy_val),
None => {
table.insert((*canonical).to_string(), legacy_val);
}
}
}
folded
}
fn merge_into(into: &mut toml::Value, from: toml::Value) {
let (Some(into_t), toml::Value::Table(from_t)) = (into.as_table_mut(), from) else {
return;
};
for (k, v) in from_t {
match into_t.get_mut(&k) {
Some(existing) => merge_into(existing, v),
None => {
into_t.insert(k, v);
}
}
}
}
pub(crate) fn migrate_file(path: &std::path::Path) -> std::io::Result<Vec<&'static str>> {
let contents = std::fs::read_to_string(path)?;
let mut doc = match contents.parse::<toml_edit::DocumentMut>() {
Ok(doc) => doc,
Err(_) => return Ok(Vec::new()),
};
let mut renamed = Vec::new();
for (legacy, canonical) in ALIASES {
let Some(legacy_item) = doc.as_table_mut().remove(legacy) else {
continue;
};
renamed.push(*legacy);
match doc.as_table_mut().get_mut(canonical) {
Some(existing) => {
if let (Some(into), Some(from)) = (existing.as_table_mut(), legacy_item.as_table())
{
for (k, v) in from.iter() {
if !into.contains_key(k) {
into.insert(k, v.clone());
}
}
}
}
None => {
doc.as_table_mut().insert(canonical, legacy_item);
}
}
}
if !renamed.is_empty() {
std::fs::write(path, doc.to_string())?;
}
Ok(renamed)
}