From bbb31269bfa449e82d3b6a20c2c3481fb3dcc316 Mon Sep 17 00:00:00 2001 From: stickies-v Date: Thu, 18 Jan 2024 17:27:36 +0000 Subject: rpc: add named arg helper Overload the Arg and MaybeArg helpers to allow accessing arguments by name as well. Also update the docs to document Arg and MaybeArg separately --- src/rpc/util.cpp | 12 +++++++++++ src/rpc/util.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 10 deletions(-) (limited to 'src/rpc') diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 51c88cc1ba..c90456fe57 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -24,6 +24,8 @@ #include #include +#include +#include #include #include @@ -728,6 +730,16 @@ std::vector> RPCHelpMan::GetArgNames() const return ret; } +size_t RPCHelpMan::GetParamIndex(std::string_view key) const +{ + auto it{std::find_if( + m_args.begin(), m_args.end(), [&key](const auto& arg) { return arg.GetName() == key;} + )}; + + CHECK_NONFATAL(it != m_args.end()); // TODO: ideally this is checked at compile time + return std::distance(m_args.begin(), it); +} + std::string RPCHelpMan::ToString() const { std::string ret; diff --git a/src/rpc/util.h b/src/rpc/util.h index ad3ed97b2e..6b35922d07 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -402,18 +402,25 @@ public: UniValue HandleRequest(const JSONRPCRequest& request) const; /** - * Helper to get a request argument. - * This function only works during m_fun(), i.e. it should only be used in - * RPC method implementations. The helper internally checks whether the - * user-passed argument isNull() and parses (from JSON) and returns the - * user-passed argument, or the default value derived from the RPCArg - * documentation, or a falsy value if no default was given. + * @brief Helper to get a required or default-valued request argument. * - * Use Arg(i) to get the argument or its default value. Otherwise, - * use MaybeArg(i) to get the optional argument or a falsy value. + * Use this function when the argument is required or when it has a default value. If the + * argument is optional and may not be provided, use MaybeArg instead. * - * The Type passed to this helper must match the corresponding - * RPCArg::Type. + * This function only works during m_fun(), i.e., it should only be used in + * RPC method implementations. It internally checks whether the user-passed + * argument isNull() and parses (from JSON) and returns the user-passed argument, + * or the default value derived from the RPCArg documentation. + * + * There are two overloads of this function: + * - Use Arg(size_t i) to get the argument (or the default value) by index. + * - Use Arg(const std::string& key) to get the argument (or the default value) by key. + * + * The Type passed to this helper must match the corresponding RPCArg::Type. + * + * @return The value of the RPC argument (or the default value) cast to type Type. + * + * @see MaybeArg for handling optional arguments without default values. */ template auto Arg(size_t i) const @@ -427,6 +434,34 @@ public: return ArgValue(i); } } + template + auto Arg(std::string_view key) const + { + return Arg(GetParamIndex(key)); + } + /** + * @brief Helper to get an optional request argument. + * + * Use this function when the argument is optional and does not have a default value. If the + * argument is required or has a default value, use Arg instead. + * + * This function only works during m_fun(), i.e., it should only be used in + * RPC method implementations. It internally checks whether the user-passed + * argument isNull() and parses (from JSON) and returns the user-passed argument, + * or a falsy value if no argument was passed. + * + * There are two overloads of this function: + * - Use MaybeArg(size_t i) to get the optional argument by index. + * - Use MaybeArg(const std::string& key) to get the optional argument by key. + * + * The Type passed to this helper must match the corresponding RPCArg::Type. + * + * @return For integral and floating-point types, a std::optional is returned. + * For other types, a Type* pointer to the argument is returned. If the + * argument is not provided, std::nullopt or a null pointer is returned. + * + * @see Arg for handling arguments that are required or have a default value. + */ template auto MaybeArg(size_t i) const { @@ -439,6 +474,11 @@ public: return ArgValue(i); } } + template + auto MaybeArg(std::string_view key) const + { + return MaybeArg(GetParamIndex(key)); + } std::string ToString() const; /** Return the named args that need to be converted from string to another JSON type */ UniValue GetArgMap() const; @@ -458,6 +498,8 @@ private: mutable const JSONRPCRequest* m_req{nullptr}; // A pointer to the request for the duration of m_fun() template R ArgValue(size_t i) const; + //! Return positional index of a parameter using its name as key. + size_t GetParamIndex(std::string_view key) const; }; /** -- cgit v1.2.3