#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 "../internal/common.hpp" #include "../io/stream.hpp" // TODO: rename Stream{Error,Result} to IO{*} namespace mijin { struct IPv4Address { std::array octets; auto operator<=>(const IPv4Address&) const MIJIN_NOEXCEPT = default; [[nodiscard]] std::string toString() const; [[nodiscard]] static Optional fromString(std::string_view stringView) MIJIN_NOEXCEPT; }; struct IPv6Address { std::array hextets; auto operator<=>(const IPv6Address&) const MIJIN_NOEXCEPT = default; [[nodiscard]] std::string toString() const; [[nodiscard]] static Optional fromString(std::string_view stringView) MIJIN_NOEXCEPT; }; using ip_address_t = std::variant; [[nodiscard]] inline std::string ipAddressToString(const ip_address_t& address) MIJIN_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) MIJIN_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) MIJIN_NOEXCEPT; [[nodiscard]] inline Task>> c_resolveHostname(std::string_view hostname) MIJIN_NOEXCEPT { return c_resolveHostname(std::string(hostname.begin(), hostname.end())); } [[nodiscard]] inline Task>> c_resolveHostname(const char* hostname) MIJIN_NOEXCEPT { return c_resolveHostname(std::string(hostname)); } } #endif // !defined(MIJIN_NET_IP_HPP_INCLUDED)