document private items

This commit is contained in:
hinto.janai 2024-07-05 20:35:52 -04:00
parent a3da860e5d
commit 57e9bd1efa
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
8 changed files with 190 additions and 131 deletions

View file

@ -10,16 +10,17 @@ This crate ports the types used in Monero's RPC interface, including:
# Modules
This crate's types are split in the following manner:
This crate has 4 modules:
- The root module; `cuprate_rpc_types`
- [`json`] module; JSON types from the `/json_rpc` endpoint
- [`bin`] module; Binary types from the binary endpoints
- [`other`] module; Misc JSON types from other endpoints
Miscellaneous types are found in the root module, e.g. [`crate::Status`].
This crate has 5 modules:
- The root module - miscellaneous items
- [`json`] - JSON types from the `/json_rpc` endpoint
- [`bin`] - Binary types from the binary endpoints
- [`other`] - Misc JSON types from other endpoints
- [`base`] - Base response types
Each type in `{json,bin,other}` come in pairs and have identical names, but are suffixed with either `Request` or `Response`. e.g. [`GetBlockCountRequest`](crate::json::GetBlockCountRequest) & [`GetBlockCountResponse`](crate::json::GetBlockCountResponse).
Miscellaneous types are found in the root module, e.g. [`crate::Status`]. Many of types here are found and used in request/response types, for example, [`crate::BlockHeader`] is used in [`crate::json::GetLastBlockHeaderResponse`].
# Documentation
The documentation for types within `{json,bin,other}` are omitted, as they can be found in [Monero's RPC documentation](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html).

View file

@ -10,6 +10,12 @@
//! - <https://github.com/monero-project/monero/commit/2899379791b7542e4eb920b5d9d58cf232806937>
//! - <https://github.com/monero-project/monero/issues/8722>
//! - <https://github.com/monero-project/monero/pull/8843>
//!
//! This library doesn't contain [`rpc_access_request_base`](https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L114-L122)
//! found in `monerod` as the type is practically deprecated.
//!
//! Although, [`AccessResponseBase`] still exists as to allow
//! outputting the same JSON fields as `monerod` (even if deprecated).
//---------------------------------------------------------------------------------------------------- Import
#[cfg(feature = "serde")]
@ -21,6 +27,7 @@ use cuprate_epee_encoding::epee_object;
use crate::{macros::monero_definition_link, Status};
//---------------------------------------------------------------------------------------------------- Requests
/* no types here... yet */
//---------------------------------------------------------------------------------------------------- Responses
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "rpc/core_rpc_server_commands_defs.h", 101..=112)]

View file

@ -1,4 +1,4 @@
//! TODO
//! JSON string containing binary data.
//---------------------------------------------------------------------------------------------------- Import

View file

@ -15,6 +15,7 @@
// What this means for Cuprate: just follow `monerod`.
//---------------------------------------------------------------------------------------------------- Import
use crate::macros::monero_definition_link;
//---------------------------------------------------------------------------------------------------- Status
// Common RPC status strings:
@ -23,39 +24,32 @@
// Note that these are _distinct_ from the ones in ZMQ:
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/message.cpp#L40-L44>.
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L78>
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 78)]
pub const CORE_RPC_STATUS_OK: &str = "OK";
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L79>
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 79)]
pub const CORE_RPC_STATUS_BUSY: &str = "BUSY";
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L80>
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 80)]
pub const CORE_RPC_STATUS_NOT_MINING: &str = "NOT MINING";
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L81>
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 81)]
pub const CORE_RPC_STATUS_PAYMENT_REQUIRED: &str = "PAYMENT REQUIRED";
/// Custom `CORE_RPC_STATUS` for usage in Cuprate.
pub const CORE_RPC_STATUS_UNKNOWN: &str = "UNKNOWN";
//---------------------------------------------------------------------------------------------------- Versions
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 90)]
/// RPC major version.
///
/// See: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L90>.
pub const CORE_RPC_VERSION_MAJOR: u32 = 3;
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 91)]
/// RPC miror version.
///
/// See: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L91>.
pub const CORE_RPC_VERSION_MINOR: u32 = 14;
#[doc = monero_definition_link!(cc73fe71162d564ffda8e549b79a350bca53c454, "/rpc/core_rpc_server_commands_defs.h", 92..=93)]
/// RPC version.
///
/// See: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L92-L93>.
///
/// ```rust
/// assert_eq!(cuprate_rpc_types::CORE_RPC_VERSION, 196_622);
/// ```
pub const CORE_RPC_VERSION: u32 = (CORE_RPC_VERSION_MAJOR << 16) | CORE_RPC_VERSION_MINOR;
//---------------------------------------------------------------------------------------------------- Tests

View file

@ -1,40 +1,47 @@
//! TODO
//! These functions define the default values
//! of optional fields in request/response types.
//!
//! For example, [`crate::json::GetBlockRequest`]
//! has a [`crate::json::GetBlockRequest::height`]
//! field and a [`crate::json::GetBlockRequest::hash`]
//! field, when the RPC interface reads JSON without
//! `height`, it will use [`default_height`] to fill that in.
//---------------------------------------------------------------------------------------------------- Import
use std::borrow::Cow;
//---------------------------------------------------------------------------------------------------- TODO
/// TODO
/// Default [`bool`] type used in request/response types.
#[inline]
pub(crate) const fn default_bool() -> bool {
false
}
/// TODO
/// Default `Cow<'static, str` type used in request/response types.
#[inline]
pub(crate) const fn default_cow_str() -> Cow<'static, str> {
Cow::Borrowed("")
}
/// TODO
/// Default [`String`] type used in request/response types.
#[inline]
pub(crate) const fn default_string() -> String {
String::new()
}
/// TODO
/// Default block height used in request/response types.
#[inline]
pub(crate) const fn default_height() -> u64 {
0
}
/// TODO
/// Default [`Vec`] used in request/response types.
#[inline]
pub(crate) const fn default_vec<T>() -> Vec<T> {
Vec::new()
}
/// TODO
/// Default [`u64`] used in request/response types.
#[inline]
pub(crate) const fn default_u64() -> u64 {
0

View file

@ -1,6 +1,7 @@
//! JSON types from the [`/json_rpc`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#json-rpc-methods) endpoint.
//!
//! <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/daemon_messages.h>.
//! Most (if not all) of these types are defined here:
//! - <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h>
//---------------------------------------------------------------------------------------------------- Import
use crate::{
@ -33,21 +34,16 @@ define_request_and_response! {
// The base type name.
GetBlockTemplate,
// The base request type.
// The request type.
//
// This must be a type found in [`crate::base`].
// It acts as a "base" that gets flattened into
// the actual request type.
// If `Request {/* fields */}` is provided, a struct is generate as-is.
//
// "Flatten" means the field(s) of a struct gets inlined
// directly into the struct during (de)serialization, see:
// <https://serde.rs/field-attrs.html#flatten>.
//
// For example here, we're using [`crate::base::EmptyRequestBase`],
// which means that there is no extra fields flattened.
//
// If a request is not specified here, it will create a `type YOUR_REQUEST_TYPE = ()`
// If `Request {}` is specified here, it will create a `pub type YOUR_REQUEST_TYPE = ()`
// instead of a `struct`, see below in other macro definitions for an example.
//
// If there are any additional attributes (`/// docs` or `#[derive]`s)
// for the struct, they go here, e.g.:
// #[derive(Copy)]
Request {
// Within the `{}` is an infinite matching pattern of:
// ```
@ -61,16 +57,20 @@ define_request_and_response! {
wallet_address: String,
},
// The base response type.
// The response type.
//
// This is the same as the request base type,
// it must be a type found in [`crate::base`].
// If `Response {/* fields */}` is used,
// this will generate a struct as-is.
//
// If there are any additional attributes (`/// docs` or `#[derive]`s)
// for the struct, they go here, e.g.:
// #[derive(Copy)]
// If a type found in [`crate::base`] is used,
// It acts as a "base" that gets flattened into
// the actual request type.
//
// "Flatten" means the field(s) of a struct gets inlined
// directly into the struct during (de)serialization, see:
// <https://serde.rs/field-attrs.html#flatten>.
ResponseBase {
// This is using `crate::base::ResponseBase`,
// This is using [`crate::base::ResponseBase`],
// so the type we generate will contain this field:
// ```
// base: crate::base::ResponseBase,
@ -103,7 +103,7 @@ define_request_and_response! {
core_rpc_server_commands_defs.h => 919..=933,
GetBlockCount,
// There is no request type specified,
// There are no request fields specified,
// this will cause the macro to generate a
// type alias to `()` instead of a `struct`.
Request {},

View file

@ -15,32 +15,34 @@
/// See the [`crate::json`] module for example usage.
///
/// # Macro internals
/// This macro has 2 branches with almost the same output:
/// 1. An empty `Request` type
/// 2. An `Request` type with fields
/// This macro uses:
/// - [`__define_request`]
/// - [`__define_response`]
/// - [`__define_request_and_response_doc`]
///
/// The first branch is the same as the second with the exception
/// that if the caller of this macro provides no `Request` type,
/// it will generate:
/// # `__define_request`
/// This macro has 2 branches. If the caller provides
/// `Request {}`, i.e. no fields, it will generate:
/// ```
/// pub type Request = ();
/// ```
/// instead of:
/// If they _did_ specify fields, it will generate:
/// ```
/// pub struct Request {/* fields */}
/// ```
///
/// This is because having a bunch of types that are all empty structs
/// means they are not compatible and it makes it cumbersome for end-users.
/// Really, they semantically are empty types, so `()` is used.
///
/// Again, other than this, the 2 branches do (should) not differ.
/// # `__define_response`
/// This macro has 2 branches. If the caller provides `Response`
/// it will generate a normal struct with no additional fields.
///
/// FIXME: there's probably a less painful way to branch here on input
/// without having to duplicate 80% of the macro. Sub-macros were attempted
/// but they ended up unreadable. So for now, make sure to fix the other
/// branch as well when making changes. The only de-duplicated part is
/// the doc generation with [`define_request_and_response_doc`].
/// If the caller provides a base type from [`crate::base`], it will
/// flatten that into the request type automatically.
///
/// E.g. `Response {/*...*/}` and `ResponseBase {/*...*/}`
/// would trigger the different branches.
macro_rules! define_request_and_response {
(
// The markdown tag for Monero RPC documentation. Not necessarily the endpoint.
@ -77,8 +79,8 @@ macro_rules! define_request_and_response {
)*
}
) => { paste::paste! {
$crate::macros::define_request! {
#[doc = $crate::macros::define_request_and_response_doc!(
$crate::macros::__define_request! {
#[doc = $crate::macros::__define_request_and_response_doc!(
"response" => [<$type_name Response>],
$monero_daemon_rpc_doc_link,
$monero_code_commit,
@ -96,12 +98,12 @@ macro_rules! define_request_and_response {
}
}
$crate::macros::define_response! {
$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!(
#[doc = $crate::macros::__define_request_and_response_doc!(
"request" => [<$type_name Request>],
$monero_daemon_rpc_doc_link,
$monero_code_commit,
@ -123,127 +125,157 @@ macro_rules! define_request_and_response {
pub(crate) use define_request_and_response;
//---------------------------------------------------------------------------------------------------- define_request
/// TODO
macro_rules! define_request {
/// Define a request type.
///
/// This is only used in [`define_request_and_response`], see it for docs.
///
/// `__` is used to notate that this shouldn't be called directly.
macro_rules! __define_request {
//------------------------------------------------------------------------------
// This branch will generate a type alias to `()` if only given `{}` as input.
(
// The response type (and any doc comments, derives, etc).
$( #[$request_type_attr:meta] )*
$request_type_name:ident {}
// Any doc comments, derives, etc.
$( #[$attr:meta] )*
// The response type.
$t:ident {}
) => {
$( #[$request_type_attr] )*
$( #[$attr] )*
///
/// This request has no inputs.
pub type $request_type_name = ();
pub type $t = ();
};
//------------------------------------------------------------------------------
// This version of the macro expects a `Request` base type.
// This branch of the macro expects fields within the `{}`,
// and will generate a `struct`
(
// The response type (and any doc comments, derives, etc).
$( #[$request_type_attr:meta] )*
$request_type_name:ident {
// Any doc comments, derives, etc.
$( #[$attr:meta] )*
// The response type.
$t:ident {
// And any fields.
$(
$( #[$request_field_attr:meta] )*
$request_field:ident: $request_field_type:ty $(= $request_field_type_default:expr)?,
$( #[$field_attr:meta] )* // field attributes
// field_name: FieldType
$field:ident: $field_type:ty $(= $field_default:expr)?,
// The $field_default is an optional extra token that represents
// a default value to pass to [`cuprate_epee_encoding::epee_object`],
// see it for usage.
)*
}
) => {
#[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] )*
pub struct $request_type_name {
$( #[$attr] )*
pub struct $t {
$(
$( #[$request_field_attr] )*
pub $request_field: $request_field_type,
$( #[$field_attr] )*
pub $field: $field_type,
)*
}
#[cfg(feature = "epee")]
::cuprate_epee_encoding::epee_object! {
$request_type_name,
$t,
$(
$request_field: $request_field_type $(= $request_field_type_default)?,
$field: $field_type $(= $field_default)?,
)*
}
};
}
pub(crate) use define_request;
pub(crate) use __define_request;
//---------------------------------------------------------------------------------------------------- define_response
/// TODO
macro_rules! define_response {
/// Define a response type.
///
/// This is only used in [`define_request_and_response`], see it for docs.
///
/// `__` is used to notate that this shouldn't be called directly.
macro_rules! __define_response {
//------------------------------------------------------------------------------
// This version of the macro expects the literal ident
// `Response` => $response_type_name.
//
// It will create a `struct` that _doesn't_ use a base from [`crate::base`],
// for example, [`crate::json::BannedResponse`] doesn't use a base, so it
// uses this branch.
(
// The response type (and any doc comments, derives, etc).
$( #[$response_type_attr:meta] )*
Response => $response_type_name:ident {
// Any doc comments, derives, etc.
$( #[$attr:meta] )*
// The response type.
Response => $t:ident {
// And any fields.
// See [`__define_request`] for docs, this does the same thing.
$(
$( #[$response_field_attr:meta] )*
$response_field:ident: $response_field_type:ty $(= $response_field_type_default:expr)?,
$( #[$field_attr:meta] )*
$field:ident: $field_type:ty $(= $field_default:expr)?,
)*
}
) => {
$( #[$response_type_attr] )*
pub struct $response_type_name {
$( #[$attr] )*
pub struct $t {
$(
$( #[$response_field_attr] )*
pub $response_field: $response_field_type,
$( #[$field_attr] )*
pub $field: $field_type,
)*
}
#[cfg(feature = "epee")]
::cuprate_epee_encoding::epee_object! {
$response_type_name,
$t,
$(
$response_field: $response_field_type $($response_field_type_default)?,
$field: $field_type $($field_default)?,
)*
}
};
//------------------------------------------------------------------------------
// This version of the macro expects a `Request` base type.
// This version of the macro expects a `Request` base type from [`crate::bases`].
(
// The response type (and any doc comments, derives, etc).
$( #[$response_type_attr:meta] )*
$response_base_type:ty => $response_type_name:ident {
// Any doc comments, derives, etc.
$( #[$attr:meta] )*
// The response base type => actual name of the struct
$base:ty => $t:ident {
// And any fields.
// See [`__define_request`] for docs, this does the same thing.
$(
$( #[$response_field_attr:meta] )*
$response_field:ident: $response_field_type:ty $(= $response_field_type_default:expr)?,
$( #[$field_attr:meta] )*
$field:ident: $field_type:ty $(= $field_default:expr)?,
)*
}
) => {
$( #[$response_type_attr] )*
pub struct $response_type_name {
$( #[$attr] )*
pub struct $t {
#[cfg_attr(feature = "serde", serde(flatten))]
pub base: $response_base_type,
pub base: $base,
$(
$( #[$response_field_attr] )*
pub $response_field: $response_field_type,
$( #[$field_attr] )*
pub $field: $field_type,
)*
}
#[cfg(feature = "epee")]
::cuprate_epee_encoding::epee_object! {
$response_type_name,
$t,
$(
$response_field: $response_field_type $(= $response_field_type_default)?,
$field: $field_type $(= $field_default)?,
)*
!flatten: base: $response_base_type,
!flatten: base: $base,
}
};
}
pub(crate) use define_response;
pub(crate) use __define_response;
//---------------------------------------------------------------------------------------------------- define_request_and_response_doc
/// Generate documentation for the types generated
/// by the [`define_request_and_response`] macro.
/// by the [`__define_request_and_response`] macro.
///
/// See it for more info on inputs.
macro_rules! define_request_and_response_doc {
///
/// `__` is used to notate that this shouldn't be called directly.
macro_rules! __define_request_and_response_doc {
(
// This labels the last `[request]` or `[response]`
// hyperlink in documentation. Input is either:
@ -287,21 +319,27 @@ macro_rules! define_request_and_response_doc {
)
};
}
pub(crate) use define_request_and_response_doc;
pub(crate) use __define_request_and_response_doc;
//---------------------------------------------------------------------------------------------------- Macro
/// Link the original `monerod` definition for RPC base types.
/// Output a string link to `monerod` source code.
macro_rules! monero_definition_link {
($commit:ident, $file_path:literal, $start:literal..=$end:literal) => {
(
$commit:ident, // Git commit hash
$file_path:literal, // File path within `monerod`'s `src/`, e.g. `rpc/core_rpc_server_commands_defs.h`
$start:literal$(..=$end:literal)? // File lines, e.g. `0..=123` or `0`
) => {
concat!(
"[Definition](https://github.com/monero-project/monero/blob/",
stringify!($commit),
"/src/",
stringify!($file_path),
$file_path,
"#L",
stringify!($start),
$(
"-L",
stringify!($end),
)?
")."
)
};

View file

@ -1,4 +1,10 @@
//! TODO
//! Miscellaneous types.
//!
//! These are `struct`s that appear in request/response types.
//! For example, [`crate::json::GetConnectionsResponse`] contains
//! the [`crate::misc::ConnectionInfo`] struct defined here.
//!
//! These types are re-exported to the root module.
//---------------------------------------------------------------------------------------------------- Lints
#![allow(
@ -16,14 +22,24 @@ use cuprate_epee_encoding::epee_object;
use crate::macros::monero_definition_link;
//---------------------------------------------------------------------------------------------------- Macros
/// TODO
/// This macro (local to this file) defines all the misc types.
///
/// This macro:
/// 1. Defines a `pub struct` with all `pub` fields
/// 2. Implements `epee` on the struct
///
/// When using, consider documenting:
/// - The original Monero definition site with [`monero_definition_link`]
/// - The request/responses where the `struct` is used
macro_rules! define_struct_and_impl_epee {
(
// Optional `struct` attributes.
$( #[$struct_attr:meta] )*
// The `struct`'s name.
$struct_name:ident {
// And any fields.
$(
$( #[$field_attr:meta] )*
$( #[$field_attr:meta] )* // Field attributes
$field_name:ident: $field_type:ty,
)*
}
@ -36,7 +52,6 @@ macro_rules! define_struct_and_impl_epee {
)*
}
#[cfg(feature = "epee")]
epee_object! {
$struct_name,
@ -313,9 +328,6 @@ define_struct_and_impl_epee! {
}
}
//---------------------------------------------------------------------------------------------------- Custom serde
// This section is for `struct`s that have custom (de)serialization code.
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {