types: Add constexpr InAddrAny / IfAddr parser
Change-Id: I08d27f3e52a703d2f3c45a886c69b081ffd69558
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/types.hpp b/src/types.hpp
index 70d9e0a..73d2778 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -369,6 +369,34 @@
}
};
+template <>
+struct ToAddr<InAddrAny>
+{
+ constexpr InAddrAny operator()(std::string_view str) const
+ {
+ if (str.find(':') == str.npos)
+ {
+ return ToAddr<in_addr>{}(str);
+ }
+ return ToAddr<in6_addr>{}(str);
+ }
+};
+
+template <>
+struct ToAddr<IfAddr>
+{
+ constexpr IfAddr operator()(std::string_view str) const
+ {
+ auto pos = str.rfind('/');
+ if (pos == str.npos)
+ {
+ throw std::invalid_argument("Invalid IfAddr");
+ }
+ return {ToAddr<InAddrAny>{}(str.substr(0, pos)),
+ DecodeInt<uint8_t, 10>{}(str.substr(pos + 1))};
+ }
+};
+
namespace detail
{
diff --git a/test/test_types.cpp b/test/test_types.cpp
index b72ecfa..5c2fa78 100644
--- a/test/test_types.cpp
+++ b/test/test_types.cpp
@@ -181,6 +181,28 @@
ta("0:1:2:3:4:5:255.168.0.1"));
}
+TEST(ToAddr, InAddrAny)
+{
+ constexpr ToAddr<InAddrAny> ta;
+ EXPECT_EQ((InAddrAny{in_addr{}}), ta("0.0.0.0"));
+ EXPECT_EQ((InAddrAny{in6_addr{}}), ta("::"));
+ EXPECT_EQ((InAddrAny{in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192,
+ 168, 0, 1}}),
+ ta("::ffff:192.168.0.1"));
+}
+
+TEST(ToAddr, IfAddr)
+{
+ constexpr ToAddr<IfAddr> ta;
+ EXPECT_THROW(ta("10"), std::invalid_argument);
+ EXPECT_THROW(ta("/10"), std::invalid_argument);
+ EXPECT_THROW(ta("0.0.0.0"), std::invalid_argument);
+ EXPECT_THROW(ta("0.0.0.0/"), std::invalid_argument);
+ EXPECT_EQ((IfAddr{in_addr{}, 0}), ta("0.0.0.0/0"));
+ EXPECT_EQ((IfAddr{in_addr{}, 30}), ta("0.0.0.0/30"));
+ EXPECT_EQ((IfAddr{in6_addr{}, 80}), ta("::/80"));
+}
+
namespace detail
{