for (auto& pair : pairs) { | for (auto& pair : pairs) { | ||||
fstream << pair.key() << ": " << pair.value() << '\n'; | fstream << pair.key() << ": " << pair.value() << '\n'; | ||||
} | } | ||||
} | |||||
nested_kvlist nested_kvlist::parse(const std::string_view line_) { | |||||
const auto line = trim(line_); | |||||
const auto semi_pos = line.find(';'); | |||||
const auto primary = trim(line.substr(0, semi_pos)); | |||||
auto tail = semi_pos == line.npos ? ""sv : trim(line.substr(semi_pos + 1)); | |||||
std::vector<pair> pairs; | |||||
while (!tail.empty()) { | |||||
const auto space_pos = tail.find(' '); | |||||
const auto item = tail.substr(0, space_pos); | |||||
const auto eq_pos = item.find('='); | |||||
if (eq_pos == item.npos) { | |||||
pairs.emplace_back(item, ""sv); | |||||
} else { | |||||
const auto key = item.substr(0, eq_pos); | |||||
const auto value = item.substr(eq_pos + 1); | |||||
pairs.emplace_back(key, value); | |||||
} | |||||
if (space_pos == tail.npos) { | |||||
break; | |||||
} | |||||
tail = trim(tail.substr(space_pos + 1)); | |||||
} | |||||
return nested_kvlist{std::string(primary), pair_list{std::move(pairs)}}; | |||||
} | } |
write_pairs(fpath, pairs.items()); | write_pairs(fpath, pairs.items()); | ||||
} | } | ||||
struct nested_kvlist { | |||||
std::string primary; | |||||
pair_list pairs; | |||||
static nested_kvlist parse(std::string_view s); | |||||
}; | |||||
template <typename What> | template <typename What> | ||||
class read_required { | class read_required { | ||||
std::string_view _key; | std::string_view _key; |
CHECK(!iter); | CHECK(!iter); | ||||
} | } | ||||
void test_nested_kvlist() { | |||||
auto check_1 = [](auto str) { | |||||
auto result = nested_kvlist::parse(str); | |||||
CHECK(result.primary == "Foo"); | |||||
CHECK(result.pairs.size() == 1); | |||||
REQUIRE(result.pairs.find("bar")); | |||||
CHECK(result.pairs.find("bar")->value() == "baz"); | |||||
}; | |||||
check_1("Foo; bar=baz"); | |||||
check_1("Foo ; bar=baz"); | |||||
check_1("Foo ; bar=baz"); | |||||
check_1("Foo ; bar=baz "); | |||||
check_1("Foo;bar=baz "); | |||||
check_1("Foo;bar=baz"); | |||||
auto check_2 = [](auto str) { | |||||
auto result = nested_kvlist::parse(str); | |||||
CHECK(result.primary == "Foo"); | |||||
CHECK(result.pairs.size() == 0); | |||||
}; | |||||
check_2("Foo"); | |||||
check_2("Foo;"); | |||||
check_2("Foo ;"); | |||||
check_2("Foo ; "); | |||||
check_2("Foo; "); | |||||
auto check_3 = [](auto str) { | |||||
auto result = nested_kvlist::parse(str); | |||||
CHECK(result.primary == "Foo bar"); | |||||
CHECK(result.pairs.size() == 2); | |||||
REQUIRE(result.pairs.find("baz")); | |||||
CHECK(result.pairs.find("baz")->value() == "meow"); | |||||
REQUIRE(result.pairs.find("quux")); | |||||
CHECK(result.pairs.find("quux")->value() == ""); | |||||
}; | |||||
check_3("Foo bar; baz=meow quux"); | |||||
check_3("Foo bar ; baz=meow quux="); | |||||
check_3("Foo bar ; quux= baz=meow"); | |||||
check_3("Foo bar ;quux= baz=meow"); | |||||
} | |||||
void run_tests() { | void run_tests() { | ||||
test_simple(); | test_simple(); | ||||
test_multi(); | test_multi(); | ||||
test_nested_kvlist(); | |||||
} | } | ||||
DDS_TEST_MAIN; | DDS_TEST_MAIN; |