use bevy_platform::collections::HashMap;
use bevy_utils::default;
use serde::{Deserialize, Serialize};
use crate::RemoteMethods;
use super::json_schema::JsonSchemaBevyType;
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenRpcDocument {
pub openrpc: String,
pub info: InfoObject,
pub methods: Vec<MethodObject>,
pub servers: Option<Vec<ServerObject>>,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct InfoObject {
pub title: String,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
impl Default for InfoObject {
fn default() -> Self {
Self {
title: "Bevy Remote Protocol".to_owned(),
version: env!("CARGO_PKG_VERSION").to_owned(),
description: None,
extensions: Default::default(),
}
}
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct ServerObject {
pub name: String,
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct MethodObject {
#[expect(
clippy::doc_markdown,
reason = "In this case, we are referring to a string, so using quotes instead of backticks makes sense."
)]
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default)]
pub params: Vec<Parameter>,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Parameter {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub schema: JsonSchemaBevyType,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
impl From<&RemoteMethods> for Vec<MethodObject> {
fn from(value: &RemoteMethods) -> Self {
value
.methods()
.iter()
.map(|e| MethodObject {
name: e.to_owned(),
..default()
})
.collect()
}
}