@@ -81,4 +81,33 @@ void lm::write_pairs(fs::path fpath, const std::vector<pair>& pairs) { | |||
for (auto& pair : pairs) { | |||
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)}}; | |||
} |
@@ -125,6 +125,13 @@ inline void write_pairs(const std::filesystem::path& fpath, const pair_list& pai | |||
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> | |||
class read_required { | |||
std::string_view _key; |
@@ -80,9 +80,52 @@ void test_multi() { | |||
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() { | |||
test_simple(); | |||
test_multi(); | |||
test_nested_kvlist(); | |||
} | |||
DDS_TEST_MAIN; |