///|
/// Decode a JSON value into a domain type using `@json.FromJson`, mapping
/// any `JsonDecodeError` into an `InvalidParams` protocol error.
pub fn[T : @json.FromJson] decode_json(
value : Json,
path? : @json.JsonPath,
) -> T raise McpError {
@json.from_json(value, path?) catch {
JsonDecodeError((p, msg)) => {
let path_str = p.to_string()
if path_str.is_empty() {
raise InvalidParams(msg)
} else {
raise InvalidParams("\{path_str}: \{msg}")
}
}
}
}
///|
fn[K : Eq + Hash, V] Map::set_opt(
self : Map[K, V],
key : K,
value : V?,
) -> Unit {
if value is Some(v) {
self[key] = v
}
}
///|
/// Copy a JSON value recursively before retaining caller-owned protocol data.
fn Json::copy(self : Json) -> Json {
match self {
Object(fields) => {
let copied : Map[String, Json] = Map([])
for key, value in fields {
copied[key] = value.copy()
}
Json::object(copied)
}
Array(values) => Json::array(values.map(fn(v) { v.copy() }))
_ => self
}
}
///|
fn Map::copy_json(self : Map[String, Json]) -> Map[String, Json] {
let copied : Map[String, Json] = Map([])
for key, value in self {
copied[key] = value.copy()
}
copied
}