#![doc = include_str!("../README.md")]
#![allow(rustdoc::bare_urls)]
#![allow(rustdoc::invalid_html_tags)]
pub mod event;
pub mod request;
mod types;
pub use crate::types::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub trait IRequest {
const COMMAND: &'static str;
type Arguments: DeserializeOwned + Serialize + Send + Sync + 'static;
type Response: DeserializeOwned + Serialize + Send + Sync + 'static;
}
pub trait IEvent {
const EVENT: &'static str;
type Body: DeserializeOwned + Serialize + Send + Sync + 'static;
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Request {
pub seq: i64,
pub command: String,
#[serde(default = "serde_json::Value::default")]
#[serde(skip_serializing_if = "serde_json::Value::is_null")]
pub arguments: serde_json::Value,
}
impl Request {
pub fn new(seq: i64, command: String, arguments: impl serde::Serialize) -> Request {
Request {
seq,
command,
arguments: serde_json::to_value(arguments).unwrap(),
}
}
}
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Response {
#[serde(rename = "request_seq")]
pub request_seq: i64,
pub success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub body: Option<serde_json::Value>,
}
impl Response {
pub fn new(
request_seq: i64,
success: bool,
message: Option<String>,
body: Option<impl serde::Serialize>,
) -> Response {
Response {
request_seq,
success,
message,
body: body.map(|b| serde_json::to_value(b).unwrap()),
}
}
pub fn success(request_seq: i64, body: impl serde::Serialize) -> Response {
Response {
request_seq,
success: true,
message: None,
body: Some(serde_json::to_value(body).unwrap()),
}
}
pub fn error(request_seq: i64, message: Option<String>, detail: Option<Message>) -> Response {
#[derive(Serialize)]
struct ErrorResponseBody {
error: Message,
}
Response {
request_seq,
success: false,
message,
body: detail.map(|error| serde_json::to_value(&ErrorResponseBody { error }).unwrap()),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Event {
pub seq: i64,
pub event: String,
#[serde(default = "serde_json::Value::default")]
#[serde(skip_serializing_if = "serde_json::Value::is_null")]
pub body: serde_json::Value,
}
impl Event {
pub fn new(seq: i64, event: String, body: impl serde::Serialize) -> Event {
Event {
seq,
event,
body: serde_json::to_value(body).unwrap(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_stopped_reason() {
let reason = StoppedEventReason::Exception;
let serialized = serde_json::to_string(&reason).unwrap();
assert_eq!(serialized, r#""exception""#);
let reason = StoppedEventReason::FunctionBreakpoint;
let serialized = serde_json::to_string(&reason).unwrap();
assert_eq!(serialized, r#""function breakpoint""#);
}
}