1use serde_json::{json, Value};
2
3use crate::{registry::Registry, rpc_method::MethodDoc};
4
5#[derive(Clone, Debug)]
7pub struct OpenRpcInfo {
8 pub title: String,
9 pub version: String,
10 pub description: Option<String>,
11}
12
13impl Default for OpenRpcInfo {
14 fn default() -> Self {
15 Self {
16 title: "Generated API".to_string(),
17 version: "1.0.0".to_string(),
18 description: None,
19 }
20 }
21}
22
23impl OpenRpcInfo {
24 fn to_value(&self) -> Value {
25 let mut info = json!({
26 "title": self.title,
27 "version": self.version,
28 });
29
30 if let Some(description) = &self.description {
31 info["description"] = json!(description);
32 }
33
34 info
35 }
36}
37
38impl Registry {
39 pub fn generate_openrpc_doc(&self) -> Value {
41 generate_openrpc_doc_with_info(self, &OpenRpcInfo::default())
42 }
43
44 pub fn generate_openrpc_doc_with_info(&self, info: &OpenRpcInfo) -> Value {
45 generate_openrpc_doc_with_info(self, info)
46 }
47}
48
49fn generate_openrpc_doc_with_info(registry: &Registry, info: &OpenRpcInfo) -> Value {
51 let methods = registry
52 .methods()
53 .iter()
54 .map(method_to_value)
55 .collect::<Vec<_>>();
56
57 json!({
58 "openrpc": "1.2.6",
59 "info": info.to_value(),
60 "methods": methods,
61 })
62}
63
64fn method_to_value(method: &MethodDoc) -> Value {
65 json!({
66 "name": method.name.clone(),
67 "summary": method.summary.clone(),
68 "deprecated": method.deprecation.clone(),
69 "tags": method.tags.clone(),
70 "params": [{
71 "name": "params",
72 "schema": method.params_schema.clone(),
73 "required": true,
74 }],
75 "result": {
76 "name": "result",
77 "schema": method.result_schema.clone(),
78 }
79 })
80}