#pragma once #if !defined(MIJIN_NET_IP_HPP_INCLUDED) #define MIJIN_NET_IP_HPP_INCLUDED 1 #include #include #include "../async/coroutine.hpp" #include "../container/optional.hpp" #include "../io/stream.hpp" // TODO: rename Stream{Error,Result} to IO{*} namespace mijin { struct IPv4Address { std::array octets; auto operator<=>(const IPv4Address&) const noexcept = default; [[nodiscard]] std::string toString() const; [[nodiscard]] static Optional fromString(std::string_view stringView) noexcept; }; struct IPv6Address { std::array hextets; auto operator<=>(const IPv6Address&) const noexcept = default; [[nodiscard]] std::string toString() const; [[nodiscard]] static Optional fromString(std::string_view stringView) noexcept; }; using ip_address_t = std::variant; [[nodiscard]] inline std::string ipAddressToString(const ip_address_t& address) noexcept { if (address.valueless_by_exception()) { return ""; } return std::visit([](const auto& addr) { return addr.toString(); }, address); } [[nodiscard]] inline Optional ipAddressFromString(std::string_view stringView) noexcept { if (Optional ipv4Address = IPv4Address::fromString(stringView); !ipv4Address.empty()) { return ip_address_t(*ipv4Address); } if (Optional ipv6Address = IPv6Address::fromString(stringView); !ipv6Address.empty()) { return ip_address_t(*ipv6Address); } return NULL_OPTIONAL; } [[nodiscard]] Task>> c_resolveHostname(std::string hostname) noexcept; } #endif // !defined(MIJIN_NET_IP_HPP_INCLUDED)