Skip to content

Commit 3fef294

Browse files
committed
Merge bitcoin/bitcoin#26706: doc: Properly report optional RPC args
fad56f7 doc: Properly report optional RPC args (MarcoFalke) fa09cb6 refactor: Introduce is_top_level_arg (MarcoFalke) fab92a5 refactor: Remove const to fix performance-move-const-arg clang-tidy errors (MarcoFalke) Pull request description: `OMITTED_NAMED_ARG` and `OMITTED` are a confusing burden: * It puts the burden on developers to pick the right one of the two * They can be interchanged without introducing a compile failure or other error * Picking the wrong one is leading to incorrect docs * They are redundant, because the correct one can already be determined by the surrounding type Fix all issues by making them an alias of each other; Pick the right one based on the outer type. ACKs for top commit: fanquake: ACK fad56f7 Tree-SHA512: 6e7193a05a852ba1618a9cb3261220c7ad3282bc5595325c04437aa811f529a88e2851e9c7dbf9878389b8aa42e98f8817b7eb0260fbb9e123da0893cbae6ca2
2 parents b52a6c0 + fad56f7 commit 3fef294

File tree

2 files changed

+52
-50
lines changed

2 files changed

+52
-50
lines changed

src/rpc/util.cpp

+11-12
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ struct Sections {
388388
const auto indent = std::string(current_indent, ' ');
389389
const auto indent_next = std::string(current_indent + 2, ' ');
390390
const bool push_name{outer_type == OuterType::OBJ}; // Dictionary keys must have a name
391+
const bool is_top_level_arg{outer_type == OuterType::NONE}; // True on the first recursion
391392

392393
switch (arg.m_type) {
393394
case RPCArg::Type::STR_HEX:
@@ -396,41 +397,41 @@ struct Sections {
396397
case RPCArg::Type::AMOUNT:
397398
case RPCArg::Type::RANGE:
398399
case RPCArg::Type::BOOL: {
399-
if (outer_type == OuterType::NONE) return; // Nothing more to do for non-recursive types on first recursion
400+
if (is_top_level_arg) return; // Nothing more to do for non-recursive types on first recursion
400401
auto left = indent;
401402
if (arg.m_opts.type_str.size() != 0 && push_name) {
402403
left += "\"" + arg.GetName() + "\": " + arg.m_opts.type_str.at(0);
403404
} else {
404405
left += push_name ? arg.ToStringObj(/*oneline=*/false) : arg.ToString(/*oneline=*/false);
405406
}
406407
left += ",";
407-
PushSection({left, arg.ToDescriptionString()});
408+
PushSection({left, arg.ToDescriptionString(/*is_named_arg=*/push_name)});
408409
break;
409410
}
410411
case RPCArg::Type::OBJ:
411412
case RPCArg::Type::OBJ_USER_KEYS: {
412-
const auto right = outer_type == OuterType::NONE ? "" : arg.ToDescriptionString();
413+
const auto right = is_top_level_arg ? "" : arg.ToDescriptionString(/*is_named_arg=*/push_name);
413414
PushSection({indent + (push_name ? "\"" + arg.GetName() + "\": " : "") + "{", right});
414415
for (const auto& arg_inner : arg.m_inner) {
415416
Push(arg_inner, current_indent + 2, OuterType::OBJ);
416417
}
417418
if (arg.m_type != RPCArg::Type::OBJ) {
418419
PushSection({indent_next + "...", ""});
419420
}
420-
PushSection({indent + "}" + (outer_type != OuterType::NONE ? "," : ""), ""});
421+
PushSection({indent + "}" + (is_top_level_arg ? "" : ","), ""});
421422
break;
422423
}
423424
case RPCArg::Type::ARR: {
424425
auto left = indent;
425426
left += push_name ? "\"" + arg.GetName() + "\": " : "";
426427
left += "[";
427-
const auto right = outer_type == OuterType::NONE ? "" : arg.ToDescriptionString();
428+
const auto right = is_top_level_arg ? "" : arg.ToDescriptionString(/*is_named_arg=*/push_name);
428429
PushSection({left, right});
429430
for (const auto& arg_inner : arg.m_inner) {
430431
Push(arg_inner, current_indent + 2, OuterType::ARR);
431432
}
432433
PushSection({indent_next + "...", ""});
433-
PushSection({indent + "]" + (outer_type != OuterType::NONE ? "," : ""), ""});
434+
PushSection({indent + "]" + (is_top_level_arg ? "" : ","), ""});
434435
break;
435436
}
436437
} // no default case, so the compiler can warn about missing cases
@@ -627,7 +628,7 @@ std::string RPCHelpMan::ToString() const
627628
if (i == 0) ret += "\nArguments:\n";
628629

629630
// Push named argument name and description
630-
sections.m_sections.emplace_back(::ToString(i + 1) + ". " + arg.GetFirstName(), arg.ToDescriptionString());
631+
sections.m_sections.emplace_back(::ToString(i + 1) + ". " + arg.GetFirstName(), arg.ToDescriptionString(/*is_named_arg=*/true));
631632
sections.m_max_pad = std::max(sections.m_max_pad, sections.m_sections.back().m_left.size());
632633

633634
// Recursively push nested args
@@ -721,7 +722,7 @@ bool RPCArg::IsOptional() const
721722
}
722723
}
723724

724-
std::string RPCArg::ToDescriptionString() const
725+
std::string RPCArg::ToDescriptionString(bool is_named_arg) const
725726
{
726727
std::string ret;
727728
ret += "(";
@@ -767,14 +768,12 @@ std::string RPCArg::ToDescriptionString() const
767768
ret += ", optional, default=" + std::get<RPCArg::Default>(m_fallback).write();
768769
} else {
769770
switch (std::get<RPCArg::Optional>(m_fallback)) {
771+
case RPCArg::Optional::OMITTED_NAMED_ARG: // Deprecated alias for OMITTED, can be removed
770772
case RPCArg::Optional::OMITTED: {
773+
if (is_named_arg) ret += ", optional"; // Default value is "null" in dicts. Otherwise,
771774
// nothing to do. Element is treated as if not present and has no default value
772775
break;
773776
}
774-
case RPCArg::Optional::OMITTED_NAMED_ARG: {
775-
ret += ", optional"; // Default value is "null"
776-
break;
777-
}
778777
case RPCArg::Optional::NO: {
779778
ret += ", required";
780779
break;

src/rpc/util.h

+41-38
Original file line numberDiff line numberDiff line change
@@ -154,21 +154,24 @@ struct RPCArg {
154154
/** Required arg */
155155
NO,
156156
/**
157+
* The arg is optional for one of two reasons:
158+
*
157159
* Optional arg that is a named argument and has a default value of
158-
* `null`. When possible, the default value should be specified.
159-
*/
160-
OMITTED_NAMED_ARG,
161-
/**
160+
* `null`.
161+
*
162162
* Optional argument with default value omitted because they are
163-
* implicitly clear. That is, elements in an array or object may not
163+
* implicitly clear. That is, elements in an array may not
164164
* exist by default.
165165
* When possible, the default value should be specified.
166166
*/
167167
OMITTED,
168+
OMITTED_NAMED_ARG, // Deprecated alias for OMITTED, can be removed
168169
};
170+
/** Hint for default value */
169171
using DefaultHint = std::string;
172+
/** Default constant value */
170173
using Default = UniValue;
171-
using Fallback = std::variant<Optional, /* hint for default value */ DefaultHint, /* default constant value */ Default>;
174+
using Fallback = std::variant<Optional, DefaultHint, Default>;
172175

173176
const std::string m_names; //!< The name of the arg (can be empty for inner args, can contain multiple aliases separated by | for named request arguments)
174177
const Type m_type;
@@ -178,10 +181,10 @@ struct RPCArg {
178181
const RPCArgOptions m_opts;
179182

180183
RPCArg(
181-
const std::string name,
182-
const Type type,
183-
const Fallback fallback,
184-
const std::string description,
184+
std::string name,
185+
Type type,
186+
Fallback fallback,
187+
std::string description,
185188
RPCArgOptions opts = {})
186189
: m_names{std::move(name)},
187190
m_type{std::move(type)},
@@ -193,11 +196,11 @@ struct RPCArg {
193196
}
194197

195198
RPCArg(
196-
const std::string name,
197-
const Type type,
198-
const Fallback fallback,
199-
const std::string description,
200-
const std::vector<RPCArg> inner,
199+
std::string name,
200+
Type type,
201+
Fallback fallback,
202+
std::string description,
203+
std::vector<RPCArg> inner,
201204
RPCArgOptions opts = {})
202205
: m_names{std::move(name)},
203206
m_type{std::move(type)},
@@ -234,7 +237,7 @@ struct RPCArg {
234237
* Return the description string, including the argument type and whether
235238
* the argument is required.
236239
*/
237-
std::string ToDescriptionString() const;
240+
std::string ToDescriptionString(bool is_named_arg) const;
238241
};
239242

240243
struct RPCResult {
@@ -263,12 +266,12 @@ struct RPCResult {
263266
const std::string m_cond;
264267

265268
RPCResult(
266-
const std::string cond,
267-
const Type type,
268-
const std::string m_key_name,
269-
const bool optional,
270-
const std::string description,
271-
const std::vector<RPCResult> inner = {})
269+
std::string cond,
270+
Type type,
271+
std::string m_key_name,
272+
bool optional,
273+
std::string description,
274+
std::vector<RPCResult> inner = {})
272275
: m_type{std::move(type)},
273276
m_key_name{std::move(m_key_name)},
274277
m_inner{std::move(inner)},
@@ -282,19 +285,19 @@ struct RPCResult {
282285
}
283286

284287
RPCResult(
285-
const std::string cond,
286-
const Type type,
287-
const std::string m_key_name,
288-
const std::string description,
289-
const std::vector<RPCResult> inner = {})
290-
: RPCResult{cond, type, m_key_name, false, description, inner} {}
288+
std::string cond,
289+
Type type,
290+
std::string m_key_name,
291+
std::string description,
292+
std::vector<RPCResult> inner = {})
293+
: RPCResult{std::move(cond), type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner)} {}
291294

292295
RPCResult(
293-
const Type type,
294-
const std::string m_key_name,
295-
const bool optional,
296-
const std::string description,
297-
const std::vector<RPCResult> inner = {},
296+
Type type,
297+
std::string m_key_name,
298+
bool optional,
299+
std::string description,
300+
std::vector<RPCResult> inner = {},
298301
bool skip_type_check = false)
299302
: m_type{std::move(type)},
300303
m_key_name{std::move(m_key_name)},
@@ -308,12 +311,12 @@ struct RPCResult {
308311
}
309312

310313
RPCResult(
311-
const Type type,
312-
const std::string m_key_name,
313-
const std::string description,
314-
const std::vector<RPCResult> inner = {},
314+
Type type,
315+
std::string m_key_name,
316+
std::string description,
317+
std::vector<RPCResult> inner = {},
315318
bool skip_type_check = false)
316-
: RPCResult{type, m_key_name, false, description, inner, skip_type_check} {}
319+
: RPCResult{type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner), skip_type_check} {}
317320

318321
/** Append the sections of the result. */
319322
void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;

0 commit comments

Comments
 (0)