promptUntilValidPickSync<T extends Object> function
- required String prompt,
- required Set<
T> options, - required StringifiedPromptOption stringify(
- int index,
- T option
- String onError(
- String input
- String selectorFormatter(
- String selector
- T? defaultValue,
- String separator = ")",
- String promptIndent = "",
- String optionsIndent = "\t",
- String errorIndent = "",
Notice
This function blocks until a full line is available. If you do not want to block the current thread, use the async version instead.
Description
Prompt the user to pick one of the values from options
.
This function only returns, if the user inputs a valid selector.
stringify
transforms each value from options
into a representable
string and associates a selector with the value.
Each selector must fulfill the following requirements:
-
it must be unique
-
it must not be a blank string (if you want to assign an option to a blank string use
defaultValue
) -
it must not contain any linefeeds (
\n
)
If the user inputs an invalid selector, then the result of onError
gets
written to stdout and the user gets prompted again until they input a
valid selector. The default function for onError
informs the user that
they picked an invalid selector.
selectorFormatter
can be used to customize the representation of the
selector. For example, this function can apply ANSI Escape Codes to affect
the appearance of the selector. By default, no formatting is applied to a
selector.
separator
is the string between each selector and its associated option. A
whitespace gets always appended to the separator
.
See promptUntilValidPick.
Implementation
T promptUntilValidPickSync<T extends Object>({
required String prompt,
required Set<T> options,
required StringifiedPromptOption Function(int index, T option) stringify,
String Function(String input)? onError,
String Function(String selector)? selectorFormatter,
T? defaultValue,
String separator = ")",
String promptIndent = "",
String optionsIndent = "\t",
String errorIndent = "",
}) {
onError ??= (input) {
return input.isBlank
? "You must pick an option"
: "There is no option for this value: $input";
};
selectorFormatter ??= (selector) => selector;
final selectorOptionsMap = <String, T>{};
final optionsStrBuf = IndentedStringBuffer(indent: optionsIndent);
void checkIsValidSelector(String selector) {
if (selector.isBlank)
throw ResultError(
selector,
functionName: "transform",
description: "A selector must not be a blank string. If you want to "
"assign an option to a blank string use 'defaultValue'.",
);
if (selector.contains("\n"))
throw ResultError(
selector,
functionName: "transform",
description: "A selector must not contain any linefeeds.",
);
if (selectorOptionsMap.containsKey(selector))
throw ResultError(
selector,
functionName: "transform",
description:
"The provided selector already exists. Each selector must be "
"unique: $selector",
);
}
var i = 0;
for (final item in options) {
final (selector: selector, option: stringifiedOption) = stringify(i, item);
checkIsValidSelector(selector);
selectorOptionsMap[selector] = item;
optionsStrBuf.writeIndented(selectorFormatter(selector));
optionsStrBuf.write("$separator ");
optionsStrBuf.write(stringifiedOption);
if (i < options.length - 1) {
optionsStrBuf.writeln();
}
i++;
}
final optionsStr = optionsStrBuf.toString();
stdout.write(promptIndent);
stdout.writeln(prompt);
stdout.writeln(optionsStr);
while (true) {
final answer = stdin.readLineSync()?.trim() ?? "";
if (null != defaultValue && answer.isBlank) return defaultValue;
final result = selectorOptionsMap[answer];
if (null != result) return result;
stdout.writeln();
stdout.write(errorIndent);
stdout.writeln(onError(answer));
stdout.writeln(optionsStr);
}
}