From 2d54d2a19a0ce59acb17cdb53f16086d5ec638d0 Mon Sep 17 00:00:00 2001 From: "hinto.janai" <hinto.janai@protonmail.com> Date: Tue, 2 Jul 2024 21:21:33 -0400 Subject: [PATCH] macros: split type generator macro up --- rpc/types/src/macros.rs | 260 +++++++++++++++++++++------------------- 1 file changed, 135 insertions(+), 125 deletions(-) diff --git a/rpc/types/src/macros.rs b/rpc/types/src/macros.rs index 1c598a36..80054db7 100644 --- a/rpc/types/src/macros.rs +++ b/rpc/types/src/macros.rs @@ -1,14 +1,12 @@ //! Macros. -//---------------------------------------------------------------------------------------------------- Struct definition -/// A template for generating 2 `struct`s with a bunch of information filled out. -/// -/// These are the RPC request and response `struct`s. +//---------------------------------------------------------------------------------------------------- define_request_and_response +/// A template for generating the RPC request and response `struct`s. /// /// These `struct`s automatically implement: /// - `Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash` /// - `serde::{Serialize, Deserialize}` -/// - `epee_encoding::EpeeObject` +/// - `cuprate_epee_encoding::EpeeObject` /// /// It's best to see the output of this macro via the documentation /// of the generated structs via `cargo doc`s to see which parts @@ -22,8 +20,8 @@ /// 2. An `Request` type with fields /// /// The first branch is the same as the second with the exception -/// that if the caller of this macro provides no fields, it will -/// generate: +/// that if the caller of this macro provides no `Request` type, +/// it will generate: /// ``` /// pub type Request = (); /// ``` @@ -44,84 +42,6 @@ /// branch as well when making changes. The only de-duplicated part is /// the doc generation with [`define_request_and_response_doc`]. macro_rules! define_request_and_response { - //------------------------------------------------------------------------------ - // This version of the macro expects a `Request` type with no fields, i.e. `Request {}`. - ( - // The markdown tag for Monero RPC documentation. Not necessarily the endpoint. - $monero_daemon_rpc_doc_link:ident, - - // The commit hash and `$file.$extension` in which this type is defined in - // the Monero codebase in the `rpc/` directory, followed by the specific lines. - $monero_code_commit:ident => - $monero_code_filename:ident. - $monero_code_filename_extension:ident => - $monero_code_line_start:literal..= - $monero_code_line_end:literal, - - // The base `struct` name. - $type_name:ident, - - // The response type (and any doc comments, derives, etc). - $( #[$response_type_attr:meta] )* - $response_base_type:ty { - // And any fields. - $( - $( #[$response_field_attr:meta] )* - $response_field:ident: $response_field_type:ty, - )* - } - ) => { paste::paste! { - #[doc = $crate::macros::define_request_and_response_doc!( - "response", - $monero_daemon_rpc_doc_link, - $monero_code_commit, - $monero_code_filename, - $monero_code_filename_extension, - $monero_code_line_start, - $monero_code_line_end, - [<$type_name Request>], - )] - /// - /// This request has no inputs. - pub type [<$type_name Request>] = (); - - #[allow(dead_code)] - #[allow(missing_docs)] - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] - $( #[$response_type_attr] )* - #[doc = $crate::macros::define_request_and_response_doc!( - "request", - $monero_daemon_rpc_doc_link, - $monero_code_commit, - $monero_code_filename, - $monero_code_filename_extension, - $monero_code_line_start, - $monero_code_line_end, - [<$type_name Response>], - )] - pub struct [<$type_name Response>] { - #[cfg_attr(feature = "serde", serde(flatten))] - pub base: $response_base_type, - - $( - $( #[$response_field_attr] )* - pub $response_field: $response_field_type, - )* - } - - #[cfg(feature = "epee")] - ::cuprate_epee_encoding::epee_object! { - [<$type_name Response>], - $( - $response_field: $response_field_type, - )* - !flatten: base: $response_base_type, - } - }}; - - //------------------------------------------------------------------------------ - // This version of the macro expects a `Request` type with fields. ( // The markdown tag for Monero RPC documentation. Not necessarily the endpoint. $monero_daemon_rpc_doc_link:ident, @@ -139,7 +59,7 @@ macro_rules! define_request_and_response { // The request type (and any doc comments, derives, etc). $( #[$request_type_attr:meta] )* - $request_base_type:ty { + Request { // And any fields. $( $( #[$request_field_attr:meta] )* @@ -157,25 +77,83 @@ macro_rules! define_request_and_response { )* } ) => { paste::paste! { - #[allow(dead_code)] - #[allow(missing_docs)] + $crate::macros::define_request! { + #[doc = $crate::macros::define_request_and_response_doc!( + "response" => [<$type_name Response>], + $monero_daemon_rpc_doc_link, + $monero_code_commit, + $monero_code_filename, + $monero_code_filename_extension, + $monero_code_line_start, + $monero_code_line_end, + )] + $( #[$request_type_attr] )* + [<$type_name Request>] { + $( + $( #[$request_field_attr] )* + $request_field: $request_field_type, + )* + } + } + + $crate::macros::define_response! { + #[allow(dead_code)] + #[allow(missing_docs)] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] + #[doc = $crate::macros::define_request_and_response_doc!( + "request" => [<$type_name Request>], + $monero_daemon_rpc_doc_link, + $monero_code_commit, + $monero_code_filename, + $monero_code_filename_extension, + $monero_code_line_start, + $monero_code_line_end, + )] + $( #[$response_type_attr] )* + $response_base_type => [<$type_name Response>] { + $( + $( #[$response_field_attr] )* + $response_field: $response_field_type, + )* + } + } + }}; +} +pub(crate) use define_request_and_response; + +//---------------------------------------------------------------------------------------------------- define_request +/// TODO +macro_rules! define_request { + ( + // The response type (and any doc comments, derives, etc). + $( #[$request_type_attr:meta] )* + $request_type_name:ident {} + ) => { + $( #[$request_type_attr] )* + /// + /// This request has no inputs. + pub type $request_type_name = (); + }; + + //------------------------------------------------------------------------------ + // This version of the macro expects a `Request` base type. + ( + // The response type (and any doc comments, derives, etc). + $( #[$request_type_attr:meta] )* + $request_type_name:ident { + // And any fields. + $( + $( #[$request_field_attr:meta] )* + $request_field:ident: $request_field_type:ty, + )* + } + ) => { + #[allow(dead_code, missing_docs)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] $( #[$request_type_attr] )* - #[doc = $crate::macros::define_request_and_response_doc!( - "response", - $monero_daemon_rpc_doc_link, - $monero_code_commit, - $monero_code_filename, - $monero_code_filename_extension, - $monero_code_line_start, - $monero_code_line_end, - [<$type_name Request>], - )] - pub struct [<$type_name Request>] { - #[cfg_attr(feature = "serde", serde(flatten))] - pub base: $request_base_type, - + pub struct $request_type_name { $( $( #[$request_field_attr] )* pub $request_field: $request_field_type, @@ -184,29 +162,61 @@ macro_rules! define_request_and_response { #[cfg(feature = "epee")] ::cuprate_epee_encoding::epee_object! { - [<$type_name Request>], + $request_type_name, $( $request_field: $request_field_type, )* - !flatten: base: $request_base_type, + } + }; +} +pub(crate) use define_request; + +//---------------------------------------------------------------------------------------------------- define_response +/// TODO +macro_rules! define_response { + ( + // The response type (and any doc comments, derives, etc). + $( #[$response_type_attr:meta] )* + Response => $response_type_name:ident { + // And any fields. + $( + $( #[$response_field_attr:meta] )* + $response_field:ident: $response_field_type:ty, + )* + } + ) => { + $( #[$response_type_attr] )* + pub struct $response_type_name { + $( + $( #[$response_field_attr] )* + pub $response_field: $response_field_type, + )* } - #[allow(dead_code)] - #[allow(missing_docs)] - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] + #[cfg(feature = "epee")] + ::cuprate_epee_encoding::epee_object! { + $response_type_name, + $( + $response_field: $response_field_type, + )* + } + }; + + //------------------------------------------------------------------------------ + // This version of the macro expects a `Request` base type. + ( + // The response type (and any doc comments, derives, etc). + $( #[$response_type_attr:meta] )* + $response_base_type:ty => $response_type_name:ident { + // And any fields. + $( + $( #[$response_field_attr:meta] )* + $response_field:ident: $response_field_type:ty, + )* + } + ) => { $( #[$response_type_attr] )* - #[doc = $crate::macros::define_request_and_response_doc!( - "request", - $monero_daemon_rpc_doc_link, - $monero_code_commit, - $monero_code_filename, - $monero_code_filename_extension, - $monero_code_line_start, - $monero_code_line_end, - [<$type_name Response>], - )] - pub struct [<$type_name Response>] { + pub struct $response_type_name { #[cfg_attr(feature = "serde", serde(flatten))] pub base: $response_base_type, @@ -218,16 +228,17 @@ macro_rules! define_request_and_response { #[cfg(feature = "epee")] ::cuprate_epee_encoding::epee_object! { - [<$type_name Response>], + $response_type_name, $( $response_field: $response_field_type, )* !flatten: base: $response_base_type, } - }}; + }; } -pub(crate) use define_request_and_response; +pub(crate) use define_response; +//---------------------------------------------------------------------------------------------------- define_request_and_response_doc /// Generate documentation for the types generated /// by the [`define_request_and_response`] macro. /// @@ -242,7 +253,7 @@ macro_rules! define_request_and_response_doc { // Remember this is linking to the _other_ type, // so if defining a `Request` type, input should // be "response". - $request_or_response:literal, + $request_or_response:literal => $request_or_response_type:ident, $monero_daemon_rpc_doc_link:ident, $monero_code_commit:ident, @@ -250,7 +261,6 @@ macro_rules! define_request_and_response_doc { $monero_code_filename_extension:ident, $monero_code_line_start:literal, $monero_code_line_end:literal, - $type_name:ident, ) => { concat!( "", @@ -272,7 +282,7 @@ macro_rules! define_request_and_response_doc { "), [", $request_or_response, "](", - stringify!($type_name), + stringify!($request_or_response_type), ")." ) };