use serde_json::{json, Value};
use crate::{registry::Registry, rpc_method::MethodDoc};
#[derive(Clone, Debug)]
pub struct OpenRpcInfo {
pub title: String,
pub version: String,
pub description: Option<String>,
}
impl Default for OpenRpcInfo {
fn default() -> Self {
Self {
title: "Generated API".to_string(),
version: "1.0.0".to_string(),
description: None,
}
}
}
impl OpenRpcInfo {
fn to_value(&self) -> Value {
let mut info = json!({
"title": self.title,
"version": self.version,
});
if let Some(description) = &self.description {
info["description"] = json!(description);
}
info
}
}
impl Registry {
pub fn generate_openrpc_doc(&self) -> Value {
generate_openrpc_doc_with_info(self, &OpenRpcInfo::default())
}
pub fn generate_openrpc_doc_with_info(&self, info: &OpenRpcInfo) -> Value {
generate_openrpc_doc_with_info(self, info)
}
}
fn generate_openrpc_doc_with_info(registry: &Registry, info: &OpenRpcInfo) -> Value {
let methods = registry
.methods()
.iter()
.map(method_to_value)
.collect::<Vec<_>>();
json!({
"openrpc": "1.2.6",
"info": info.to_value(),
"methods": methods,
})
}
fn method_to_value(method: &MethodDoc) -> Value {
json!({
"name": method.name.clone(),
"summary": method.summary.clone(),
"deprecated": method.deprecation.clone(),
"tags": method.tags.clone(),
"params": [{
"name": "params",
"schema": method.params_schema.clone(),
"required": true,
}],
"result": {
"name": "result",
"schema": method.result_schema.clone(),
}
})
}