Skip to main content

roboticus_core/config/
migration.rs

1#[derive(Debug, Default, Clone, PartialEq, Eq)]
2pub struct ConfigMigrationReport {
3    pub renamed_server_host_to_bind: bool,
4    pub routing_mode_heuristic_rewritten: bool,
5    pub deny_on_empty_allowlist_hardened: bool,
6    pub removed_credit_cooldown_seconds: bool,
7}
8
9impl ConfigMigrationReport {
10    pub fn changed(&self) -> bool {
11        self.renamed_server_host_to_bind
12            || self.routing_mode_heuristic_rewritten
13            || self.deny_on_empty_allowlist_hardened
14            || self.removed_credit_cooldown_seconds
15    }
16}
17
18pub fn migrate_removed_legacy_config(raw: &str) -> Result<Option<(String, ConfigMigrationReport)>> {
19    let mut doc: toml::Value = toml::from_str(raw)?;
20    let mut report = ConfigMigrationReport::default();
21    let root = match doc.as_table_mut() {
22        Some(root) => root,
23        None => return Ok(None),
24    };
25
26    if let Some(server) = root.get_mut("server").and_then(|v| v.as_table_mut())
27        && let Some(host) = server.remove("host")
28    {
29        if !server.contains_key("bind") {
30            server.insert("bind".to_string(), host);
31        }
32        report.renamed_server_host_to_bind = true;
33    }
34
35    if let Some(models) = root.get_mut("models").and_then(|v| v.as_table_mut())
36        && let Some(routing) = models.get_mut("routing").and_then(|v| v.as_table_mut())
37        && let Some(mode) = routing.get_mut("mode")
38        && let Some(mode_str) = mode.as_str()
39        && mode_str == "heuristic"
40    {
41        *mode = toml::Value::String("metascore".into());
42        report.routing_mode_heuristic_rewritten = true;
43    }
44
45    if let Some(security) = root.get_mut("security").and_then(|v| v.as_table_mut())
46        && let Some(deny) = security.get_mut("deny_on_empty_allowlist")
47        && deny.as_bool() == Some(false)
48    {
49        *deny = toml::Value::Boolean(true);
50        report.deny_on_empty_allowlist_hardened = true;
51    }
52
53    if let Some(circuit_breaker) = root.get_mut("circuit_breaker").and_then(|v| v.as_table_mut())
54        && circuit_breaker.remove("credit_cooldown_seconds").is_some()
55    {
56        report.removed_credit_cooldown_seconds = true;
57    }
58
59    if !report.changed() {
60        return Ok(None);
61    }
62
63    Ok(Some((toml::to_string_pretty(&doc)?, report)))
64}