pub fn align_account(body: &[u8], known: &[String], serving: &str) -> Option<Vec<u8>> {
if serving.is_empty() {
return None;
}
let mut v: serde_json::Value = serde_json::from_slice(body).ok()?;
let uid = v.get("metadata")?.get("user_id")?.as_str()?;
let mut out = uid.to_string();
for other in known {
if other != serving && !other.is_empty() && out.contains(other.as_str()) {
out = out.replace(other.as_str(), serving);
}
}
if out == uid {
return None;
}
*v.get_mut("metadata")?.get_mut("user_id")? = serde_json::Value::String(out);
serde_json::to_vec(&v).ok()
}
#[cfg(test)]
mod tests {
use super::*;
const A: &str = "11111111-2222-3333-4444-555555555555";
const B: &str = "66666666-7777-8888-9999-000000000000";
fn body_with(uid: &str) -> Vec<u8> {
serde_json::to_vec(&serde_json::json!({
"model": "claude-opus-5",
"messages": [{"role": "user", "content": "keep me intact"}],
"metadata": {"user_id": uid},
}))
.unwrap()
}
#[test]
fn the_serving_accounts_uuid_replaces_the_other_ones() {
let uid = format!("{{\"device_id\":\"d1\",\"account_uuid\":\"{A}\",\"session\":\"{A}\"}}");
let out = align_account(&body_with(&uid), &[A.into(), B.into()], B).expect("rewritten");
let v: serde_json::Value = serde_json::from_slice(&out).unwrap();
let new_uid = v["metadata"]["user_id"].as_str().unwrap();
assert!(!new_uid.contains(A), "the other account's uuid is gone");
assert_eq!(new_uid.matches(B).count(), 2, "both occurrences replaced");
assert_eq!(v["model"], "claude-opus-5");
assert_eq!(v["messages"][0]["content"], "keep me intact");
}
#[test]
fn nothing_to_change_returns_none_so_the_body_is_forwarded_verbatim() {
let uid = format!("{{\"account_uuid\":\"{B}\"}}");
assert!(align_account(&body_with(&uid), &[A.into(), B.into()], B).is_none());
let foreign = "{\"account_uuid\":\"deadbeef-0000-0000-0000-000000000000\"}";
assert!(align_account(&body_with(foreign), &[A.into(), B.into()], B).is_none());
}
#[test]
fn a_body_without_the_field_or_without_json_is_left_alone() {
let no_meta = serde_json::to_vec(&serde_json::json!({"model": "x"})).unwrap();
assert!(align_account(&no_meta, &[A.into()], B).is_none());
assert!(align_account(b"not json at all", &[A.into()], B).is_none());
let uid = format!("{{\"account_uuid\":\"{A}\"}}");
assert!(align_account(&body_with(&uid), &[A.into()], "").is_none());
}
}
pub fn swap_model(body: &[u8], fallback: &str) -> Option<Vec<u8>> {
if fallback.is_empty() {
return None;
}
let mut v: serde_json::Value = serde_json::from_slice(body).ok()?;
let current = v.get("model")?.as_str()?;
if current == fallback {
return None;
}
*v.get_mut("model")? = serde_json::Value::String(fallback.to_string());
serde_json::to_vec(&v).ok()
}
#[cfg(test)]
mod model_tests {
use super::*;
fn model_of(b: &[u8]) -> String {
serde_json::from_slice::<serde_json::Value>(b).unwrap()["model"]
.as_str()
.unwrap()
.to_string()
}
#[test]
fn the_model_is_replaced_and_nothing_else_is() {
let body = br#"{"model":"claude-opus-5","max_tokens":100,"messages":[{"role":"user"}]}"#;
let out = swap_model(body, "claude-sonnet-5").expect("rewritten");
assert_eq!(model_of(&out), "claude-sonnet-5");
let v: serde_json::Value = serde_json::from_slice(&out).unwrap();
assert_eq!(v["max_tokens"], 100, "the rest of the request is untouched");
assert!(v["messages"].is_array());
}
#[test]
fn asking_for_the_fallback_already_is_left_alone() {
let body = br#"{"model":"claude-sonnet-5"}"#;
assert!(swap_model(body, "claude-sonnet-5").is_none());
}
#[test]
fn a_request_with_no_model_is_left_alone() {
assert!(swap_model(br#"{"messages":[]}"#, "claude-sonnet-5").is_none());
assert!(swap_model(b"not json", "claude-sonnet-5").is_none());
}
#[test]
fn no_fallback_configured_changes_nothing() {
assert!(swap_model(br#"{"model":"claude-opus-5"}"#, "").is_none());
}
}