diff --git a/src/option_types.hh b/src/option_types.hh index fd6b3b14..3d9548f9 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -7,6 +7,7 @@ #include "coord.hh" #include "array_view.hh" #include "id_map.hh" +#include "hash_map.hh" #include "flags.hh" #include "enum.hh" @@ -144,6 +145,46 @@ struct option_type_name> static String name() { return format("str-to-{}-map", option_type_name::name()); } }; +template +String option_to_string(const HashMap& opt) +{ + String res; + for (auto it = begin(opt); it != end(opt); ++it) + { + if (it != begin(opt)) + res += list_separator; + String elem = escape(option_to_string(it->key), '=', '\\') + "=" + + escape(option_to_string(it->value), '=', '\\'); + res += escape(elem, list_separator, '\\'); + } + return res; +} + +template +void option_from_string(StringView str, HashMap& opt) +{ + opt.clear(); + for (auto& elem : split(str, list_separator, '\\')) + { + Vector pair_str = split(elem, '=', '\\'); + if (pair_str.size() != 2) + throw runtime_error("map option expects key=value"); + Key key; + Value value; + option_from_string(pair_str[0], key); + option_from_string(pair_str[1], value); + opt.insert({ std::move(key), std::move(value) }); + } +} + +template +struct option_type_name> +{ + static String name() { return format("{}-to-{}-map", + option_type_name::name(), + option_type_name::name()); } +}; + constexpr char tuple_separator = '|'; template