blob: 9de490c9a562e44b8f7232d1feec50b268d97703 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "src/lib/line_input/options_line_input.h"
#include "lib/fit/defer.h"
#include "src/lib/fxl/strings/split_string.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace line_input {
void OptionsLineInputBase::PromptOptions(const std::vector<std::string>& options,
OptionsCallback callback) {
options_ = std::move(options);
callback_ = std::move(callback);
}
void OptionsLineInputBase::HandleLine(const std::string& line, bool canceled) {
FXL_DCHECK(is_active());
fit::result<void, std::string> result = fit::ok();
std::vector<int> chosen_options;
auto defer_callback =
fit::defer([&result, &chosen_options, callback = std::move(callback_)]() mutable {
callback(std::move(result), chosen_options);
});
if (canceled) {
result = fit::error("");
return;
}
auto options = fxl::SplitString(line, " ", fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
if (options.empty()) {
result = fit::error("No options given.");
return;
}
// All entries should be indices.
std::vector<int> indices;
indices.reserve(options.size());
for (const auto& option : options) {
int index = -1;
if (!fxl::StringToNumberWithError(option, &index) ||
(index <= 0 || index > static_cast<int>(options_.size()))) {
result = fit::error(fxl::StringPrintf("Invalid index %s", option.ToString().c_str()));
return;
}
indices.push_back(index - 1);
}
// Fill in the chosen options.
chosen_options = std::move(indices);
}
// OptionsLineInputStdout --------------------------------------------------------------------------
bool OptionsLineInputStdout::OnInput(char c) {
if (!LineInputBase::OnInput(c))
return false;
bool canceled = eof();
HandleLine(line(), canceled);
return true;
}
} // namespace line_input