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;