use serde_json::{Value, json}; pub const CURRENT_PROTOCOL_VERSION: &str = "2025-11-25"; pub const DEFAULT_PROTOCOL_VERSION: &str = "2025-03-26"; pub const SUPPORTED_PROTOCOL_VERSIONS: &[&str] = &[ DEFAULT_PROTOCOL_VERSION, "2025-06-18", CURRENT_PROTOCOL_VERSION, ]; pub fn request_id(message: &Value) -> Value { message.get("id").cloned().unwrap_or(Value::Null) } pub fn method_name(message: &Value) -> Option<&str> { message.get("method").and_then(Value::as_str) } pub fn params(message: &Value) -> Value { message .get("params") .cloned() .unwrap_or_else(|| Value::Object(Default::default())) } pub fn is_notification(message: &Value) -> bool { method_name(message).is_some() && message.get("id").is_none() } pub fn is_request(message: &Value) -> bool { method_name(message).is_some() && message.get("id").is_some() } pub fn is_response(message: &Value) -> bool { method_name(message).is_none() && (message.get("result").is_some() || message.get("error").is_some()) } pub fn jsonrpc_result(id: Value, result: Value) -> Value { json!({ "jsonrpc": "2.0", "id": id, "result": result }) } pub fn jsonrpc_error(id: Value, code: i64, message: impl Into) -> Value { json!({ "jsonrpc": "2.0", "id": id, "error": { "code": code, "message": message.into() } }) } pub fn negotiated_protocol_version(requested: &str) -> Option<&'static str> { SUPPORTED_PROTOCOL_VERSIONS .iter() .copied() .find(|version| *version == requested) }