Add string util functions for parsing percentage values

This commit is contained in:
John Novak 2023-11-19 11:59:41 +10:00 committed by John Novak
parent fc4bb6a2a5
commit 28af4aa25e
3 changed files with 82 additions and 0 deletions

View file

@ -358,6 +358,10 @@ std::optional<float> parse_float(const std::string& s);
//
std::optional<int> parse_int(const std::string& s, const int base = 10);
// Returned percentage values are unscaled.
std::optional<float> parse_percentage_with_percent_sign(const std::string_view s);
std::optional<float> parse_percentage_with_optional_percent_sign(const std::string_view s);
template <typename... Args>
std::string format_string(const std::string& format, const Args&... args) noexcept
{

View file

@ -378,3 +378,27 @@ std::optional<int> parse_int(const std::string& s, const int base)
}
return {};
}
std::optional<float> parse_percentage(const std::string_view s,
const bool is_percent_sign_optional)
{
if (!is_percent_sign_optional) {
if (!ends_with(s, "%")) {
return {};
}
}
return {parse_float(strip_suffix(s, "%"))};
}
std::optional<float> parse_percentage_with_percent_sign(const std::string_view s)
{
const auto is_percent_sign_optional = false;
return parse_percentage(s, is_percent_sign_optional);
}
std::optional<float> parse_percentage_with_optional_percent_sign(const std::string_view s)
{
const auto is_percent_sign_optional = true;
return parse_percentage(s, is_percent_sign_optional);
}

View file

@ -411,6 +411,60 @@ TEST(ParseInt, Invalid)
EXPECT_EQ(parse_int(" "), empty);
}
TEST(ParsePercentageWithOptionalPercentSign, Valid)
{
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("1%"), 1.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("1"), 1.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("100%"), 100.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("100"), 100.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("150%"), 150.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("150"), 150.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("-5%"), -5.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("-5"), -5.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("0%"), 0.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("0"), 0.0f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("-110.5%"), -110.5f);
EXPECT_EQ(*parse_percentage_with_optional_percent_sign("-110.5"), -110.5f);
}
TEST(ParsePercentageWithPercentSign, Valid)
{
EXPECT_EQ(*parse_percentage_with_percent_sign("1%"), 1.0f);
EXPECT_EQ(*parse_percentage_with_percent_sign("100%"), 100.0f);
EXPECT_EQ(*parse_percentage_with_percent_sign("150%"), 150.0f);
EXPECT_EQ(*parse_percentage_with_percent_sign("-5%"), -5.0f);
EXPECT_EQ(*parse_percentage_with_percent_sign("0%"), 0.0f);
EXPECT_EQ(*parse_percentage_with_percent_sign("-110.5%"), -110.5f);
}
TEST(ParsePercentageWithPercentSign, Invalid)
{
std::optional<float> empty = {};
EXPECT_EQ(parse_percentage_with_percent_sign("100"), empty);
EXPECT_EQ(parse_percentage_with_percent_sign("0"), empty);
EXPECT_EQ(parse_percentage_with_percent_sign("-1"), empty);
EXPECT_EQ(parse_percentage_with_percent_sign("100a"), empty);
EXPECT_EQ(parse_percentage_with_percent_sign("sfafsd"), empty);
EXPECT_EQ(parse_percentage_with_percent_sign(""), empty);
EXPECT_EQ(parse_percentage_with_percent_sign(" "), empty);
}
TEST(ParsePercentageWithOptionalPercentSign, Invalid)
{
std::optional<float> empty = {};
EXPECT_EQ(parse_percentage_with_optional_percent_sign("100a"), empty);
EXPECT_EQ(parse_percentage_with_optional_percent_sign("sfafsd"), empty);
EXPECT_EQ(parse_percentage_with_optional_percent_sign(""), empty);
EXPECT_EQ(parse_percentage_with_optional_percent_sign(" "), empty);
}
TEST(FormatString, Valid)
{
EXPECT_EQ(format_string(""), "");