Skip to content

Commit 2772030

Browse files
fanquakeknst
authored andcommitted
Merge 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
1 parent 3173806 commit 2772030

2 files changed

Lines changed: 57 additions & 54 deletions

File tree

src/rpc/util.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ struct Sections {
359359
const auto indent = std::string(current_indent, ' ');
360360
const auto indent_next = std::string(current_indent + 2, ' ');
361361
const bool push_name{outer_type == OuterType::OBJ}; // Dictionary keys must have a name
362+
const bool is_top_level_arg{outer_type == OuterType::NONE}; // True on the first recursion
362363

363364
switch (arg.m_type) {
364365
case RPCArg::Type::STR_HEX:
@@ -367,41 +368,41 @@ struct Sections {
367368
case RPCArg::Type::AMOUNT:
368369
case RPCArg::Type::RANGE:
369370
case RPCArg::Type::BOOL: {
370-
if (outer_type == OuterType::NONE) return; // Nothing more to do for non-recursive types on first recursion
371+
if (is_top_level_arg) return; // Nothing more to do for non-recursive types on first recursion
371372
auto left = indent;
372373
if (arg.m_type_str.size() != 0 && push_name) {
373374
left += "\"" + arg.GetName() + "\": " + arg.m_type_str.at(0);
374375
} else {
375376
left += push_name ? arg.ToStringObj(/*oneline=*/false) : arg.ToString(/*oneline=*/false);
376377
}
377378
left += ",";
378-
PushSection({left, arg.ToDescriptionString()});
379+
PushSection({left, arg.ToDescriptionString(/*is_named_arg=*/push_name)});
379380
break;
380381
}
381382
case RPCArg::Type::OBJ:
382383
case RPCArg::Type::OBJ_USER_KEYS: {
383-
const auto right = outer_type == OuterType::NONE ? "" : arg.ToDescriptionString();
384+
const auto right = is_top_level_arg ? "" : arg.ToDescriptionString(/*is_named_arg=*/push_name);
384385
PushSection({indent + (push_name ? "\"" + arg.GetName() + "\": " : "") + "{", right});
385386
for (const auto& arg_inner : arg.m_inner) {
386387
Push(arg_inner, current_indent + 2, OuterType::OBJ);
387388
}
388389
if (arg.m_type != RPCArg::Type::OBJ) {
389390
PushSection({indent_next + "...", ""});
390391
}
391-
PushSection({indent + "}" + (outer_type != OuterType::NONE ? "," : ""), ""});
392+
PushSection({indent + "}" + (is_top_level_arg ? "" : ","), ""});
392393
break;
393394
}
394395
case RPCArg::Type::ARR: {
395396
auto left = indent;
396397
left += push_name ? "\"" + arg.GetName() + "\": " : "";
397398
left += "[";
398-
const auto right = outer_type == OuterType::NONE ? "" : arg.ToDescriptionString();
399+
const auto right = is_top_level_arg ? "" : arg.ToDescriptionString(/*is_named_arg=*/push_name);
399400
PushSection({left, right});
400401
for (const auto& arg_inner : arg.m_inner) {
401402
Push(arg_inner, current_indent + 2, OuterType::ARR);
402403
}
403404
PushSection({indent_next + "...", ""});
404-
PushSection({indent + "]" + (outer_type != OuterType::NONE ? "," : ""), ""});
405+
PushSection({indent + "]" + (is_top_level_arg ? "" : ","), ""});
405406
break;
406407
}
407408
} // no default case, so the compiler can warn about missing cases
@@ -595,7 +596,7 @@ std::string RPCHelpMan::ToString() const
595596
if (i == 0) ret += "\nArguments:\n";
596597

597598
// Push named argument name and description
598-
sections.m_sections.emplace_back(::ToString(i + 1) + ". " + arg.GetFirstName(), arg.ToDescriptionString());
599+
sections.m_sections.emplace_back(::ToString(i + 1) + ". " + arg.GetFirstName(), arg.ToDescriptionString(/*is_named_arg=*/true));
599600
sections.m_max_pad = std::max(sections.m_max_pad, sections.m_sections.back().m_left.size());
600601

601602
// Recursively push nested args
@@ -651,7 +652,7 @@ bool RPCArg::IsOptional() const
651652
}
652653
}
653654

654-
std::string RPCArg::ToDescriptionString() const
655+
std::string RPCArg::ToDescriptionString(bool is_named_arg) const
655656
{
656657
std::string ret;
657658
ret += "(";
@@ -697,14 +698,12 @@ std::string RPCArg::ToDescriptionString() const
697698
ret += ", optional, default=" + std::get<RPCArg::Default>(m_fallback).write();
698699
} else {
699700
switch (std::get<RPCArg::Optional>(m_fallback)) {
701+
case RPCArg::Optional::OMITTED_NAMED_ARG: // Deprecated alias for OMITTED, can be removed
700702
case RPCArg::Optional::OMITTED: {
703+
if (is_named_arg) ret += ", optional"; // Default value is "null" in dicts. Otherwise,
701704
// nothing to do. Element is treated as if not present and has no default value
702705
break;
703706
}
704-
case RPCArg::Optional::OMITTED_NAMED_ARG: {
705-
ret += ", optional"; // Default value is "null"
706-
break;
707-
}
708707
case RPCArg::Optional::NO: {
709708
ret += ", required";
710709
break;

src/rpc/util.h

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -157,21 +157,25 @@ struct RPCArg {
157157
/** Required arg */
158158
NO,
159159
/**
160+
* The arg is optional for one of two reasons:
161+
*
160162
* Optional arg that is a named argument and has a default value of
161-
* `null`. When possible, the default value should be specified.
162-
*/
163-
OMITTED_NAMED_ARG,
164-
/**
163+
* `null`.
164+
*
165165
* Optional argument with default value omitted because they are
166-
* implicitly clear. That is, elements in an array or object may not
166+
* implicitly clear. That is, elements in an array may not
167167
* exist by default.
168168
* When possible, the default value should be specified.
169169
*/
170170
OMITTED,
171+
OMITTED_NAMED_ARG, // Deprecated alias for OMITTED, can be removed
171172
};
173+
/** Hint for default value */
172174
using DefaultHint = std::string;
175+
/** Default constant value */
173176
using Default = UniValue;
174-
using Fallback = std::variant<Optional, /* hint for default value */ DefaultHint, /* default constant value */ Default>;
177+
using Fallback = std::variant<Optional, DefaultHint, Default>;
178+
175179
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)
176180
const Type m_type;
177181
const bool m_hidden;
@@ -182,13 +186,13 @@ struct RPCArg {
182186
const std::vector<std::string> m_type_str; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_type_str.at(0) will override the type of the value in a key-value pair, m_type_str.at(1) will override the type in the argument description.
183187

184188
RPCArg(
185-
const std::string name,
186-
const Type type,
187-
const Fallback fallback,
188-
const std::string description,
189-
const std::string oneline_description = "",
190-
const std::vector<std::string> type_str = {},
191-
const bool hidden = false)
189+
std::string name,
190+
Type type,
191+
Fallback fallback,
192+
std::string description,
193+
std::string oneline_description = "",
194+
std::vector<std::string> type_str = {},
195+
bool hidden = false)
192196
: m_names{std::move(name)},
193197
m_type{std::move(type)},
194198
m_hidden{hidden},
@@ -201,13 +205,13 @@ struct RPCArg {
201205
}
202206

203207
RPCArg(
204-
const std::string name,
205-
const Type type,
206-
const Fallback fallback,
207-
const std::string description,
208-
const std::vector<RPCArg> inner,
209-
const std::string oneline_description = "",
210-
const std::vector<std::string> type_str = {})
208+
std::string name,
209+
Type type,
210+
Fallback fallback,
211+
std::string description,
212+
std::vector<RPCArg> inner,
213+
std::string oneline_description = "",
214+
std::vector<std::string> type_str = {})
211215
: m_names{std::move(name)},
212216
m_type{std::move(type)},
213217
m_hidden{false},
@@ -242,7 +246,7 @@ struct RPCArg {
242246
* Return the description string, including the argument type and whether
243247
* the argument is required.
244248
*/
245-
std::string ToDescriptionString() const;
249+
std::string ToDescriptionString(bool is_named_arg) const;
246250
};
247251

248252
struct RPCResult {
@@ -270,12 +274,12 @@ struct RPCResult {
270274
const std::string m_cond;
271275

272276
RPCResult(
273-
const std::string cond,
274-
const Type type,
275-
const std::string m_key_name,
276-
const bool optional,
277-
const std::string description,
278-
const std::vector<RPCResult> inner = {})
277+
std::string cond,
278+
Type type,
279+
std::string m_key_name,
280+
bool optional,
281+
std::string description,
282+
std::vector<RPCResult> inner = {})
279283
: m_type{std::move(type)},
280284
m_key_name{std::move(m_key_name)},
281285
m_inner{std::move(inner)},
@@ -288,19 +292,19 @@ struct RPCResult {
288292
}
289293

290294
RPCResult(
291-
const std::string cond,
292-
const Type type,
293-
const std::string m_key_name,
294-
const std::string description,
295-
const std::vector<RPCResult> inner = {})
296-
: RPCResult{cond, type, m_key_name, false, description, inner} {}
295+
std::string cond,
296+
Type type,
297+
std::string m_key_name,
298+
std::string description,
299+
std::vector<RPCResult> inner = {})
300+
: RPCResult{std::move(cond), type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner)} {}
297301

298302
RPCResult(
299-
const Type type,
300-
const std::string m_key_name,
301-
const bool optional,
302-
const std::string description,
303-
const std::vector<RPCResult> inner = {})
303+
Type type,
304+
std::string m_key_name,
305+
bool optional,
306+
std::string description,
307+
std::vector<RPCResult> inner = {})
304308
: m_type{std::move(type)},
305309
m_key_name{std::move(m_key_name)},
306310
m_inner{std::move(inner)},
@@ -312,10 +316,10 @@ struct RPCResult {
312316
}
313317

314318
RPCResult(
315-
const Type type,
316-
const std::string m_key_name,
317-
const std::string description,
318-
const std::vector<RPCResult> inner = {})
319+
Type type,
320+
std::string m_key_name,
321+
std::string description,
322+
std::vector<RPCResult> inner = {})
319323
: RPCResult{type, m_key_name, false, description, inner} {}
320324

321325
/** Append the sections of the result. */

0 commit comments

Comments
 (0)