use serde_json::Value;
pub fn interpolate_path(template: &str, payload: &Value) -> String {
if !template.contains('{') {
return template.to_string();
}
let mut result = String::with_capacity(template.len() + 32);
let mut chars = template.chars().peekable();
while let Some(ch) = chars.next() {
if ch != '{' {
result.push(ch);
continue;
}
let mut key = String::new();
let mut closed = false;
for inner in chars.by_ref() {
if inner == '}' {
closed = true;
break;
}
key.push(inner);
}
if closed && !key.is_empty() {
let value = payload.get(&key).and_then(|v| v.as_str()).unwrap_or("");
result.push_str(value);
} else {
result.push('{');
result.push_str(&key);
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn static_path_returned_unchanged() {
let p = json!({});
assert_eq!(interpolate_path("/places/hall", &p), "/places/hall");
assert_eq!(interpolate_path("/players", &p), "/players");
assert_eq!(interpolate_path("/", &p), "/");
assert_eq!(interpolate_path("", &p), "");
}
#[test]
fn single_placeholder_resolved() {
let p = json!({ "session_id": "abc123" });
assert_eq!(
interpolate_path("/players/{session_id}", &p),
"/players/abc123"
);
}
#[test]
fn single_placeholder_at_suffix() {
let p = json!({ "user_id": "u42" });
assert_eq!(
interpolate_path("/places/house/{user_id}", &p),
"/places/house/u42"
);
}
#[test]
fn multiple_placeholders() {
let p = json!({ "room_type": "arena", "user_id": "u9" });
assert_eq!(
interpolate_path("/rooms/{room_type}/players/{user_id}", &p),
"/rooms/arena/players/u9"
);
}
#[test]
fn missing_key_produces_empty_segment() {
let p = json!({});
assert_eq!(interpolate_path("/players/{session_id}", &p), "/players/");
}
#[test]
fn non_string_value_produces_empty_segment() {
let p = json!({ "session_id": 42 });
assert_eq!(interpolate_path("/players/{session_id}", &p), "/players/");
}
#[test]
fn malformed_unclosed_placeholder_emitted_verbatim() {
let p = json!({ "session_id": "abc" });
assert_eq!(
interpolate_path("/players/{session_id", &p),
"/players/{session_id"
);
}
#[test]
fn placeholder_at_root() {
let p = json!({ "entity": "ship" });
assert_eq!(interpolate_path("/{entity}", &p), "/ship");
}
}