Add a function for staticSuggestions
This new function wraps the boilerplate that's needed for making static
suggestion list. This could also be used for the dump_args parser (to
get rid of more boilerplate), but it's a bigger change, so I'll leave
that for another patch.
Also, the parser really NEEDS its attribute to be the unused_type,
otherwise weird stuff happens, ghosts appear and it also messes with the
attributes of other parsers. I don't know why, but oh well.
This thing has to copy because a std::initializer_list cannot be
properly captured by value in the inner lambda. Such a code builds, but
it won't do the right thing.
Change-Id: Ida0bcc86124b88d686ac86cf4743d220db86f59b
Co-authored-by: Jan Kundrát <jan.kundrat@cesnet.cz>
diff --git a/src/grammars.hpp b/src/grammars.hpp
index a6df5c9..71af580 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -15,6 +15,25 @@
#include "leaf_data.hpp"
#include "path_parser.hpp"
+/**
+ * Returns a parser that generates suggestions based on a Completion set.
+ * Usage:
+ * const auto suggestSomeStuff = staticSuggestions({"some", "stuff", "yay"});
+ *
+ * You can use this as a standard parser in a Spirit grammar.
+ */
+auto staticSuggestions(const std::initializer_list<std::string>& strings)
+{
+ std::set<Completion> completions;
+ std::transform(begin(strings), end(strings), std::inserter(completions, completions.end()),
+ [](const auto s) { return Completion{s, " "}; });
+ return as<x3::unused_type>[x3::eps[([completions](auto& ctx) {
+ auto& parserContext = x3::get<parser_context_tag>(ctx);
+ parserContext.m_suggestions = completions;
+ parserContext.m_completionIterator = _where(ctx).begin();
+ })]];
+}
+
#if BOOST_VERSION <= 107700
namespace boost::spirit::x3::traits
{
@@ -148,11 +167,7 @@
const auto copy_source = x3::rule<class source, Datastore>{"source datastore"} = datastore;
const auto copy_destination = x3::rule<class source, Datastore>{"destination datastore"} = datastore;
-const auto datastoreSuggestions = x3::eps[([](auto& ctx) {
- auto& parserContext = x3::get<parser_context_tag>(ctx);
- parserContext.m_suggestions = {Completion{"running", " "}, Completion{"startup", " "}};
- parserContext.m_completionIterator = _where(ctx).begin();
-})];
+const auto datastoreSuggestions = staticSuggestions({"running", "startup"});
struct copy_args : x3::parser<copy_args> {
using attribute_type = copy_;
@@ -317,11 +332,7 @@
auto const exec_def =
exec_::name > -(space_separator > -as<dataPath_>[RpcActionPath<AllowInput::No>{}]);
-const auto dsTargetSuggestions = x3::eps[([](auto& ctx) {
- auto& parserContext = x3::get<parser_context_tag>(ctx);
- parserContext.m_suggestions = {Completion{"running", " "}, Completion{"startup", " "}, Completion{"operational", " "}};
- parserContext.m_completionIterator = _where(ctx).begin();
-})];
+const auto dsTargetSuggestions = staticSuggestions({"running", "startup", "operational"});
struct ds_target_table : x3::symbols<DatastoreTarget> {
ds_target_table()
@@ -334,7 +345,7 @@
} const ds_target_table;
auto const switch_rule_def =
- switch_::name > space_separator > as<x3::unused_type>[dsTargetSuggestions] > ds_target_table;
+ switch_::name > space_separator > dsTargetSuggestions > ds_target_table;
auto const cancel_def =
cancel_::name >> x3::attr(cancel_{});