Repository: bitcoin/bitcoin
File: src/rpc/util.h (C/C++)

Code before:
    RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);

    UniValue HandleRequest(const JSONRPCRequest& request) const;
    /**
     * @brief Helper to get a required or default-valued request argument.
     *
     * 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.
     *
     * 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
    {
        // Return argument (required or with default value).
        if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
            // Return numbers by value.
            return ArgValue<R>(i);
        } else {
            // Return everything else by reference.
            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.

Review comment (suggestion):
nit: there's still a remaining reference to `Arg<Type>(i)` in `CheckRequiredOrDefault`:

<details>
<summary>git diff on fadb3eb57b</summary>

```diff
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index f683878054..d4079d9f37 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -673,7 +673,7 @@ static const UniValue* DetailMaybeArg(CheckFn* check, const std::vector<RPCArg>&
 
 static void CheckRequiredOrDefault(const RPCArg& param)
 {
-    // Must use `Arg<Type>(i)` to get the argument or its default value.
+    // Must use `Arg<Type>` to get the argument or its default value.
     const bool required{
         std::holds_alternative<RPCArg::Optional>(param.m_fallback) && RPCArg::Optional::NO == std::get<RPCArg::Optional>(param.m_fallback),
     };

```
</details>


Code after:
    RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);

    UniValue HandleRequest(const JSONRPCRequest& request) const;
    /**
     * @brief Helper to get a required or default-valued request argument.
     *
     * 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.
     *
     * 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.
     *
     * The instantiation of this helper for type R must match the corresponding RPCArg::Type.
     *
     * @return The value of the RPC argument (or the default value) cast to type R.
     *
     * @see MaybeArg for handling optional arguments without default values.
     */
    template <typename R>
    auto Arg(std::string_view key) const
    {
        auto i{GetParamIndex(key)};
        // Return argument (required or with default value).
        if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
            // Return numbers by value.
            return ArgValue<R>(i);
        } else {
            // Return everything else by reference.
            return ArgValue<const R&>(i);
        }
    }
    /**
     * @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.
     *
     * The instantiation of this helper for type R must match the corresponding RPCArg::Type.
     *
     * @return For integral and floating-point types, a std::optional<R> is returned.
     *         For other types, a R* 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.