cuprate_test_utils/rpc/data/macros.rs
1//! Macros.
2
3//---------------------------------------------------------------------------------------------------- define_request_and_response
4/// A template for generating the RPC request and response `const` data.
5///
6/// See the [`crate::json`] module for example usage.
7///
8/// # Macro internals
9/// This macro uses:
10/// - [`define_request_and_response_doc`]
11/// - [`define_request_and_response_test`]
12macro_rules! define_request_and_response {
13 (
14 // The markdown tag for Monero daemon RPC documentation. Not necessarily the endpoint.
15 //
16 // Adding `(json)` after this will trigger the macro to automatically
17 // add a `serde_json` test for the request/response data.
18 $monero_daemon_rpc_doc_link:ident $(($test:ident))?,
19
20 // The base name.
21 // Attributes added here will apply to _both_
22 // request and response types.
23 $( #[$attr:meta] )*
24 $name:ident: $type:ty,
25
26 // The request type (and any doc comments, derives, etc).
27 $( #[$request_attr:meta] )*
28 Request = $request:expr_2021;
29
30 // The response type (and any doc comments, derives, etc).
31 $( #[$response_attr:meta] )*
32 Response = $response:expr_2021;
33 ) => { paste::paste! {
34 #[doc = $crate::rpc::data::macros::define_request_and_response_doc!(
35 "response" => [<$name:upper _RESPONSE>],
36 $monero_daemon_rpc_doc_link,
37 )]
38 ///
39 $( #[$attr] )*
40 ///
41 $( #[$request_attr] )*
42 ///
43 $(
44 #[doc = $crate::rpc::data::macros::define_request_and_response_doc_test!([<$name:upper _REQUEST>], $test)]
45 )?
46 pub const [<$name:upper _REQUEST>]: $type = $request;
47
48 #[doc = $crate::rpc::data::macros::define_request_and_response_doc!(
49 "request" => [<$name:upper _REQUEST>],
50 $monero_daemon_rpc_doc_link,
51 )]
52 ///
53 $( #[$attr] )*
54 ///
55 $( #[$response_attr] )*
56 ///
57 $(
58 #[doc = $crate::rpc::data::macros::define_request_and_response_doc_test!([<$name:upper _RESPONSE>], $test)]
59 )?
60 pub const [<$name:upper _RESPONSE>]: $type = $response;
61 }};
62}
63pub(super) use define_request_and_response;
64
65//---------------------------------------------------------------------------------------------------- define_request_and_response_doc
66/// Generate documentation for the types generated
67/// by the [`define_request_and_response`] macro.
68///
69/// See it for more info on inputs.
70macro_rules! define_request_and_response_doc {
71 (
72 // This labels the last `[request]` or `[response]`
73 // hyperlink in documentation. Input is either:
74 // - "request"
75 // - "response"
76 //
77 // Remember this is linking to the _other_ type,
78 // so if defining a `Request` type, input should
79 // be "response".
80 $request_or_response:literal => $request_or_response_type:ident,
81 $monero_daemon_rpc_doc_link:ident,
82 ) => {
83 concat!(
84 "",
85 "[Documentation](",
86 "https://www.getmonero.org/resources/developer-guides/daemon-rpc.html",
87 "#",
88 stringify!($monero_daemon_rpc_doc_link),
89 "), [",
90 $request_or_response,
91 "](",
92 stringify!($request_or_response_type),
93 ")."
94 )
95 };
96}
97pub(super) use define_request_and_response_doc;
98
99//---------------------------------------------------------------------------------------------------- define_request_and_response_test
100/// Generate documentation for the types generated
101/// by the [`define_request_and_response`] macro.
102///
103/// See it for more info on inputs.
104macro_rules! define_request_and_response_doc_test {
105 // `/json_rpc` doc test.
106 (
107 // The ident of the `const` request/response.
108 $name:ident,
109 json_rpc
110 ) => {
111 concat!(
112 "```rust\n",
113 "use cuprate_test_utils::rpc::data::json::*;\n",
114 "use serde_json::{to_value, Value};\n",
115 "\n",
116 "let value = serde_json::from_str::<Value>(&",
117 stringify!($name),
118 ").unwrap();\n",
119 "let Value::Object(map) = value else {\n",
120 " panic!();\n",
121 "};\n",
122 "\n",
123 r#"assert_eq!(map.get("jsonrpc").unwrap(), "2.0");"#,
124 "\n",
125 r#"map.get("id").unwrap();"#,
126 "\n\n",
127 r#"if map.get("method").is_some() {"#,
128 "\n",
129 r#" return;"#,
130 "\n",
131 "}\n",
132 "\n",
133 r#"if map.get("result").is_none() {"#,
134 "\n",
135 r#" map.get("error").unwrap();"#,
136 "\n",
137 "}\n",
138 "\n",
139 "```\n",
140 )
141 };
142
143 // Other JSON endpoint doc test.
144 (
145 $name:ident,
146 other
147 ) => {
148 concat!(
149 "```rust\n",
150 "use cuprate_test_utils::rpc::data::other::*;\n",
151 "use serde_json::{to_value, Value};\n",
152 "\n",
153 "let value = serde_json::from_str::<Value>(&",
154 stringify!($name),
155 ");\n",
156 "```\n",
157 )
158 };
159}
160pub(super) use define_request_and_response_doc_test;