///|
/// Response is a Message used as a reply to a call Request.
/// It will have the same ID as the call it is a response to.
pub(all) struct Response {
// id of the request this is a response to.
id : ID
// result is the content of the response or an error.
result : Result[Json, WireError]
} derive(Debug, Eq)
///|
pub impl Show for Response with fn output(self, logger) {
logger.write_string(
(
$|{id: \{self.id}, result: \{Repr(self.result).to_string()}}
),
)
}
///|
test "Response show interface" {
let res = { id: ID::number(42), result: Ok(Json::string("hello")) }
inspect(
res,
content=(
#|{id: Number(42), result: Ok(String("hello"))}
),
)
}
///|
/// WireError is a jsonrpc2 error message.
pub(all) struct WireError {
code : Int
message : String
data : Json?
} derive(Debug, Eq, FromJson, ToJson)
///|
pub impl Show for WireError with fn output(self, logger) {
logger.write_string(
(
$|{code: \{self.code}, message: \{self.message.escape(quote=true)}, data: \{Repr(self.data).to_string()}}
),
)
}
///|
test "WireError show interface" {
let err = {
code: -32601,
message: "Method not found".to_string(),
data: Some({ "jsonrpc": "2.0".to_json() }.to_json()),
}
inspect(
err,
content=(
#|{code: -32601, message: "Method not found", data: Some(Object({ "jsonrpc": String("2.0") }))}
),
)
}
///|
pub impl ToJson for Response with fn to_json(self) {
let obj = { "jsonrpc": "2.0".to_json() }
match self.id {
String(s) => obj["id"] = s.to_json()
Number(n) => obj["id"] = n.to_double().to_json()
}
match self.result {
Ok(result) => obj["result"] = result
Err(err) => obj["error"] = err.to_json()
}
obj.to_json()
}
///|
pub impl @json.FromJson for Response with fn from_json(json, path) {
guard json is Object(obj) else {
raise @json.JsonDecodeError((path, "expected object"))
}
match obj {
{ "jsonrpc": String("2.0"), "id": Number(id, ..), "result": result, .. } =>
{ id: Number(id.to_int64()), result: Ok(result) }
{ "jsonrpc": String("2.0"), "id": String(id), "result": result, .. } =>
{ id: String(id), result: Ok(result) }
{
"jsonrpc": String("2.0"),
"id": Number(id, ..),
"error": {
"code": Number(code, ..),
"message": String(message),
"data": data,
..
},
..
} =>
{
id: Number(id.to_int64()),
result: Err({ code: code.to_int(), message, data: Some(data) }),
}
{
"jsonrpc": String("2.0"),
"id": Number(id, ..),
"error": { "code": Number(code, ..), "message": String(message), .. },
..
} =>
{
id: Number(id.to_int64()),
result: Err({ code: code.to_int(), message, data: None }),
}
{
"jsonrpc": String("2.0"),
"id": String(id),
"error": {
"code": Number(code, ..),
"message": String(message),
"data": data,
..
},
..
} =>
{
id: String(id),
result: Err({ code: code.to_int(), message, data: Some(data) }),
}
{
"jsonrpc": String("2.0"),
"id": String(id),
"error": { "code": Number(code, ..), "message": String(message), .. },
..
} =>
{
id: String(id),
result: Err({ code: code.to_int(), message, data: None }),
}
_ =>
raise @json.JsonDecodeError(
(path, "expected jsonrpc, id, and result or error"),
)
}
}