use serde::{Deserialize, Serialize};
use serde_json::Value;
pub const JSONRPC_VERSION: &str = "2.0";
#[derive(Debug, Deserialize, Serialize)]
pub struct JsonRpcRequest {
pub jsonrpc: String,
pub method: String,
#[serde(default)]
pub params: Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<Value>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct JsonRpcNotification {
pub jsonrpc: String,
pub method: String,
#[serde(default)]
pub params: Value,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct JsonRpcResponse {
pub jsonrpc: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<JsonRpcError>,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<Value>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct JsonRpcError {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
#[derive(Debug, Serialize)]
#[serde(untagged)]
pub enum JsonRpcResponseOrNotification {
Response(JsonRpcResponse),
Notification(ProcessedNotification),
}
#[derive(Debug, Serialize)]
pub struct ProcessedNotification {
#[serde(skip)]
pub processed: bool,
}
#[derive(Debug, Deserialize)]
pub struct SandboxStartParams {
pub sandbox: String,
pub namespace: String,
pub config: Option<SandboxConfig>,
}
#[derive(Debug, Deserialize)]
pub struct SandboxStopParams {
pub sandbox: String,
pub namespace: String,
}
#[derive(Debug, Deserialize)]
pub struct SandboxMetricsGetParams {
pub sandbox: Option<String>,
pub namespace: String,
}
#[derive(Debug, Deserialize)]
pub struct SandboxConfig {
pub image: Option<String>,
pub memory: Option<u32>,
pub cpus: Option<u8>,
#[serde(default)]
pub volumes: Vec<String>,
#[serde(default)]
pub ports: Vec<String>,
#[serde(default)]
pub envs: Vec<String>,
#[serde(default)]
pub depends_on: Vec<String>,
pub workdir: Option<String>,
pub shell: Option<String>,
#[serde(default)]
pub scripts: std::collections::HashMap<String, String>,
pub exec: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct SandboxReplRunParams {
pub code: String,
pub language: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct SandboxReplGetOutputParams {
pub execution_id: String,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct SandboxCommandRunParams {
pub command: String,
#[serde(default)]
pub args: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct SandboxCommandGetOutputParams {
pub execution_id: String,
}
impl JsonRpcRequest {
pub fn new(method: String, params: Value, id: Value) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
method,
params,
id: Some(id),
}
}
pub fn new_notification(method: String, params: Value) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
method,
params,
id: None,
}
}
pub fn is_notification(&self) -> bool {
self.id.is_none()
}
}
impl ProcessedNotification {
pub fn processed() -> Self {
Self { processed: true }
}
}
impl JsonRpcResponseOrNotification {
pub fn success(result: Value, id: Option<Value>) -> Self {
Self::Response(JsonRpcResponse::success(result, id))
}
pub fn error(error: JsonRpcError, id: Option<Value>) -> Self {
Self::Response(JsonRpcResponse::error(error, id))
}
pub fn response(response: JsonRpcResponse) -> Self {
Self::Response(response)
}
pub fn notification(notification: ProcessedNotification) -> Self {
Self::Notification(notification)
}
pub fn no_response() -> Self {
Self::Notification(ProcessedNotification::processed())
}
}
impl JsonRpcResponse {
pub fn success(result: Value, id: Option<Value>) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
result: Some(result),
error: None,
id,
}
}
pub fn error(error: JsonRpcError, id: Option<Value>) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
result: None,
error: Some(error),
id,
}
}
}
#[derive(Debug, Serialize)]
pub struct RegularMessageResponse {
pub message: String,
}
#[derive(Debug, Serialize)]
pub struct SystemStatusResponse {}
#[derive(Debug, Serialize)]
pub struct SandboxStatusResponse {
pub sandboxes: Vec<SandboxStatus>,
}
#[derive(Debug, Serialize)]
pub struct SandboxConfigResponse {}
#[derive(Debug, Serialize)]
pub struct SandboxStatus {
pub namespace: String,
pub name: String,
pub running: bool,
pub cpu_usage: Option<f32>,
pub memory_usage: Option<u64>,
pub disk_usage: Option<u64>,
}
impl axum::response::IntoResponse for JsonRpcResponseOrNotification {
fn into_response(self) -> axum::response::Response {
match self {
JsonRpcResponseOrNotification::Response(response) => {
(axum::http::StatusCode::OK, axum::Json(response)).into_response()
}
JsonRpcResponseOrNotification::Notification(_notification) => {
axum::http::StatusCode::OK.into_response()
}
}
}
}