aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
authorstickies-v <stickies-v@protonmail.com>2024-01-18 17:27:36 +0000
committerstickies-v <stickies-v@protonmail.com>2024-03-01 13:51:21 +0000
commitbbb31269bfa449e82d3b6a20c2c3481fb3dcc316 (patch)
treeb4221ad0b182b4d55ef84c338db67658e54f7809 /src/rpc
parent13525e0c248eab9b199583cde76430c6da2426e2 (diff)
downloadbitcoin-bbb31269bfa449e82d3b6a20c2c3481fb3dcc316.tar.xz
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
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/util.cpp12
-rw-r--r--src/rpc/util.h62
2 files changed, 64 insertions, 10 deletions
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 <util/string.h>
#include <util/translation.h>
+#include <algorithm>
+#include <iterator>
#include <string_view>
#include <tuple>
@@ -728,6 +730,16 @@ std::vector<std::pair<std::string, bool>> 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<Type>(i) to get the argument or its default value. Otherwise,
- * use MaybeArg<Type>(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<Type>(size_t i) to get the argument (or the default value) by index.
+ * - Use Arg<Type>(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 <typename R>
auto Arg(size_t i) const
@@ -427,6 +434,34 @@ public:
return ArgValue<const R&>(i);
}
}
+ template<typename R>
+ auto Arg(std::string_view key) const
+ {
+ return Arg<R>(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<Type>(size_t i) to get the optional argument by index.
+ * - Use MaybeArg<Type>(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<Type> 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 <typename R>
auto MaybeArg(size_t i) const
{
@@ -439,6 +474,11 @@ public:
return ArgValue<const R*>(i);
}
}
+ template<typename R>
+ auto MaybeArg(std::string_view key) const
+ {
+ return MaybeArg<R>(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 <typename R>
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;
};
/**