+
+ if (ret.error() == CIDRNetworkError::INVALID_IP_SLASH_CIDR) {
+ throw IPAddressFormatException(sformat(
+ "Invalid ipSlashCidr specified. Expected IP/CIDR format, got '{}'",
+ ipSlashCidr));
+ }
+
+ // Handler the remaining error cases. We re-parse the ip/mask pair
+ // to make error messages more meaningful
+ auto const vec = splitIpSlashCidr(ipSlashCidr);
+
+ switch (ret.error()) {
+ case CIDRNetworkError::INVALID_IP:
+ CHECK_GE(vec.size(), 1);
+ throw IPAddressFormatException(
+ sformat("Invalid IP address {}", vec.at(0)));
+ case CIDRNetworkError::INVALID_CIDR:
+ CHECK_GE(vec.size(), 2);
+ throw IPAddressFormatException(
+ sformat("Mask value '{}' not a valid mask", vec.at(1)));
+ case CIDRNetworkError::CIDR_MISMATCH: {
+ auto const subnet = IPAddress::tryFromString(vec.at(0)).value();
+ auto cidr = static_cast<uint8_t>(
+ (defaultCidr > -1) ? defaultCidr : (subnet.isV4() ? 32 : 128));
+
+ throw IPAddressFormatException(sformat(
+ "CIDR value '{}' is > network bit count '{}'",
+ vec.size() == 2 ? vec.at(1) : to<string>(cidr),
+ subnet.bitCount()));
+ }
+ default:
+ // unreachable
+ break;
+ }
+
+ CHECK(0);
+
+ return CIDRNetwork{};
+}
+
+// public static
+Expected<CIDRNetwork, CIDRNetworkError> IPAddress::tryCreateNetwork(
+ StringPiece ipSlashCidr,
+ int defaultCidr,
+ bool applyMask) {
+ if (defaultCidr > std::numeric_limits<uint8_t>::max()) {
+ return makeUnexpected(CIDRNetworkError::INVALID_DEFAULT_CIDR);
+ }
+
+ auto const vec = splitIpSlashCidr(ipSlashCidr);
+ auto const elemCount = vec.size();