///|
/// BiDi request message
priv struct BidiRequest {
id : Int
method_name : String
params : Json?
}
///|
/// BiDi response message
priv struct BidiResponse {
id : Int
result : Json?
error : BidiError?
}
///|
/// BiDi error payload
priv struct BidiError {
error : String
message : String
stacktrace : String
}
///|
/// BiDi event message
priv struct BidiEvent {
event_method : String
params : Json
}
///|
/// Outgoing BiDi message
priv enum BidiOutMessage {
Response(BidiResponse)
Event(BidiEvent)
Raw(String)
}
///|
/// Process incoming JSON message
fn BidiProtocol::process_message(
self : BidiProtocol,
json_str : String,
) -> Result[Unit, String] {
let parsed = match @protocol_wire.parse_request(json_str) {
Ok(request) => request
Err(err) => return Err(err)
}
let request : BidiRequest = {
id: parsed.id,
method_name: parsed.method_name,
params: parsed.params,
}
self.dispatch(request)
}
///|
/// Take and clear outgoing messages
fn BidiProtocol::take_messages(self : BidiProtocol) -> Array[BidiOutMessage] {
let out = self.outbox
self.outbox = []
out
}
///|
/// Convert outgoing message to JSON string
fn BidiOutMessage::to_json(self : BidiOutMessage) -> String {
match self {
Response(resp) => response_to_json(resp)
Event(evt) => event_to_json(evt)
Raw(raw) => raw
}
}
///|
/// Send success response
fn BidiProtocol::send_success(
self : BidiProtocol,
id : Int,
result : Json?,
) -> Unit {
let resp : BidiResponse = { id, result, error: None }
self.outbox.push(Response(resp))
}
///|
/// Send a pre-serialized response JSON string
fn BidiProtocol::send_raw(self : BidiProtocol, json : String) -> Unit {
self.outbox.push(Raw(json))
}
///|
/// Send error response
fn BidiProtocol::send_error(
self : BidiProtocol,
id : Int,
code : String,
message : String,
) -> Unit {
let err : BidiError = { error: code, message, stacktrace: "" }
let resp : BidiResponse = { id, result: None, error: Some(err) }
self.outbox.push(Response(resp))
}
///|
/// Response JSON serialization
fn response_to_json(resp : BidiResponse) -> String {
match resp.error {
Some(err) =>
@protocol_wire.error_response_to_json(
resp.id,
err.error,
err.message,
err.stacktrace,
)
None => @protocol_wire.success_response_to_json(resp.id, resp.result)
}
}
///|
/// Event JSON serialization
fn event_to_json(evt : BidiEvent) -> String {
@protocol_wire.event_to_json(evt.event_method, evt.params)
}