///|
pub(all) suberror NetError String derive(Show)

///|
typealias Array as IOArray

///|
pub(all) enum SocketAddr {
  V4(String, UInt16) // IPv4 address and port
  V6(String, UInt16, flowinfo~ : UInt, scope_id~ : UInt) // IPv6 address and port
} derive(Show)

///|
pub(open) trait ToSocketAddrs {
  to_socket_addr(self : Self) -> Iter[SocketAddr] raise NetError
}

///|
pub impl ToSocketAddrs for SocketAddr with to_socket_addr(self : SocketAddr) -> Iter[
  SocketAddr,
] {
  [self].iter()
}

///|
pub(all) enum Domain {
  IPv4
  IPv6
  Unix
} derive(Show)

///|
pub(open) trait ToDomain {
  to_domain(self : Self) -> Domain raise NetError
}

///|
pub impl ToDomain for Domain with to_domain(self : Domain) -> Domain {
  self
}

///|
pub fn Domain::from_address(addr : SocketAddr) -> Domain {
  match addr {
    V4(_, _) => IPv4
    V6(_, _, ..) => IPv6
  }
}

///|
pub impl ToDomain for Unit with to_domain(self : Unit) -> Domain {
  Domain::IPv4 // Default to IPv4 if no domain specified
}

///|
pub(all) enum Type {
  Stream // SOCK_STREAM
  Datagram // SOCK_DGRAM
  Raw // SOCK_RAW
} derive(Show)

///|
pub(open) trait ToType {
  to_type(self : Self) -> Type raise NetError
}

///|
pub impl ToType for Type with to_type(self : Type) -> Type {
  self
}

///|
pub(all) enum Protocol {
  TCP // IPPROTO_TCP
  UDP // IPPROTO_UDP
  ICMPV4 // IPPROTO_ICMP
  ICMPV6 // IPPROTO_ICMPV6
} derive(Show)

///|
pub(open) trait ToProtocol {
  to_protocol(self : Self) -> Protocol raise NetError
}

///|
pub impl ToProtocol for Protocol with to_protocol(self : Protocol) -> Protocol {
  self
}

///|
pub(all) enum Shutdown {
  Read // SHUT_RD
  Write // SHUT_WR
  Both // SHUT_RDWR
} derive(Show)

///|
pub(open) trait ToShutdown {
  to_shutdown(self : Self) -> Shutdown raise NetError
}

///|
pub impl ToShutdown for Shutdown with to_shutdown(self : Shutdown) -> Shutdown {
  self
}

///|
pub(all) enum AIFlags {
  AI_PASSIVE
  AI_CANONNAME
  AI_ALL
  AI_NUMERICHOST
  AI_NUMERICSERV
  AI_ADDRCONFIG
  AI_V4MAPPED
} derive(Show)

///|
pub(open) trait ToAIFlags {
  to_ai_flags(self : Self) -> AIFlags raise NetError
}