///|
/// Message covers all jsonrpc2 message types.
/// They share no common functionality, but are a closed set of concrete types
/// that are allowed to implement this interface. The message types are Request
/// and Response.
pub enum Message {
// Request is a jsonrpc2 request message.
Request(Request)
// Response is a jsonrpc2 response message.
Response(Response)
// BatchRequest is an array of requests.
BatchRequest(Array[Request])
// BatchResponse is an array of responses.
BatchResponse(Array[Response])
} derive(Show, Eq)
///|
pub impl ToJson for Message with to_json(self) {
match self {
Request(req) => req.to_json()
Response(res) => res.to_json()
BatchRequest(arr_req) => arr_req.to_json()
BatchResponse(arr_res) => arr_res.to_json()
}
}
///|
pub impl @json.FromJson for Message with from_json(json, path) {
let req : Result[Request, @json.JsonDecodeError] = try? @json.from_json(json)
if req is Ok(req) {
return Request(req)
}
let res : Result[Response, @json.JsonDecodeError] = try? @json.from_json(json)
if res is Ok(res) {
return Response(res)
}
let arr_req : Result[Array[Request], @json.JsonDecodeError] = try? @json.from_json(
json,
)
if arr_req is Ok(arr_req) {
return BatchRequest(arr_req)
}
let arr_res : Result[Array[Response], @json.JsonDecodeError] = try? @json.from_json(
json,
)
if arr_res is Ok(arr_res) {
return BatchResponse(arr_res)
}
raise @json.JsonDecodeError((path, "expected request(s) or response(s)"))
}
///|
/// new_notification constructs a new notification message for the supplied
/// method and parameters.
pub fn new_notification(method_ : String, params : Json) -> Message {
Request({ id: None, method_, params })
}
///|
/// new_call constructs a new call message for the supplied ID, method and
/// parameters.
pub fn new_call(id : ID, method_ : String, params : Json) -> Message {
Request({ id: Some(id), method_, params })
}
///|
/// new_response constructs a new Response message.
pub fn new_response(id : ID, result : Result[Json, WireError]) -> Message {
Response({ id, result })
}
///|
/// new_batch_request constructs a new batch request message for the supplied
/// requests.
pub fn new_batch_request(messages : Array[Message]) -> Message {
let requests = messages.filter_map(Message::as_request)
BatchRequest(requests)
}
///|
/// new_batch_response constructs a new batch response message for the supplied
/// responses.
pub fn new_batch_response(messages : Array[Message]) -> Message {
let responses = messages.filter_map(Message::as_response)
BatchResponse(responses)
}
///|
pub fn Message::as_call(self : Message) -> Request? {
guard self is Request(req) else { return None }
guard req.id is Some(_) else { return None }
Some(req)
}
///|
pub fn Message::as_notification(self : Message) -> Request? {
guard self is Request(req) else { return None }
guard req.id is None else { return None }
Some(req)
}
///|
pub fn Message::as_request(self : Message) -> Request? {
if self is Request(req) {
Some(req)
} else {
None
}
}
///|
pub fn Message::as_response(self : Message) -> Response? {
if self is Response(res) {
Some(res)
} else {
None
}
}
///|
/// as_batch_request returns the message as a batch request if it is one.
pub fn Message::as_batch_request(self : Message) -> Array[Request]? {
if self is BatchRequest(arr_req) {
Some(arr_req)
} else {
None
}
}
///|
/// as_batch_response returns the message as a batch response if it is one.
pub fn Message::as_batch_response(self : Message) -> Array[Response]? {
if self is BatchResponse(arr_res) {
Some(arr_res)
} else {
None
}
}