// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
struct SockaddrIn(Bytes)
///|
pub impl ToJson for SockaddrIn with to_json(self : SockaddrIn) -> Json {
{ "addr": self.addr(), "port": self.port() }
}
///|
extern "c" fn uv_sockaddr_in_make() -> SockaddrIn = "moonbit_uv_sockaddr_in_make"
///|
#borrow(addr)
extern "c" fn uv_sockaddr_in_port(addr : SockaddrIn) -> UInt = "moonbit_uv_sockaddr_in_port"
///|
pub fn SockaddrIn::port(self : SockaddrIn) -> UInt16 {
Int16::from_int(uv_sockaddr_in_port(self).reinterpret_as_int()).reinterpret_as_uint16()
}
///|
extern "c" fn uv_INET_ADDRSTRLEN() -> Int = "moonbit_uv_INET_ADDRSTRLEN"
///|
extern "c" fn uv_INET6_ADDRSTRLEN() -> Int = "moonbit_uv_INET6_ADDRSTRLEN"
///|
let _INET_ADDRSTRLEN : Int = uv_INET_ADDRSTRLEN()
///|
let _INET6_ADDRSTRLEN : Int = uv_INET6_ADDRSTRLEN()
///|
struct InAddr(UInt)
///|
pub extern "c" fn InAddr::new(
b0 : Byte,
b1 : Byte,
b2 : Byte,
b3 : Byte,
) -> InAddr = "moonbit_uv_in_addr_make"
///|
pub extern "c" fn InAddr::to_bytes(self : InAddr) -> Bytes = "moonbit_uv_in_addr_to_bytes"
///|
#borrow(addr)
extern "c" fn uv_sockaddr_in_addr(addr : SockaddrIn) -> UInt = "moonbit_uv_sockaddr_in_addr"
///|
pub fn SockaddrIn::addr(self : SockaddrIn) -> InAddr {
InAddr(uv_sockaddr_in_addr(self))
}
///|
#borrow(src, dst)
extern "c" fn uv_in_addr_ntop(src : UInt, dst : FixedArray[Byte]) -> Int = "moonbit_uv_in_addr_ntop"
///|
pub fn InAddr::ntop(self : InAddr) -> Bytes raise Errno {
let dst : FixedArray[Byte] = FixedArray::make(_INET_ADDRSTRLEN, 0)
let status = uv_in_addr_ntop(self.0, dst)
if status < 0 {
raise Errno::of_int(status)
}
let len = for i in 0..<_INET_ADDRSTRLEN {
if dst[i] == 0 {
break i
}
} else {
_INET_ADDRSTRLEN
}
let buf : FixedArray[Byte] = FixedArray::make(len, 0)
buf.unsafe_blit(0, dst, 0, len)
buf.unsafe_reinterpret_as_bytes()
}
///|
pub impl ToJson for InAddr with to_json(self : InAddr) -> Json {
wtf8_to_string(self.ntop()).to_json() catch {
_ => self.to_bytes().to_array().to_json()
}
}
///|
#borrow(src, dst)
extern "c" fn uv_in_addr_pton(src : Bytes, dst : Ref[InAddr]) -> Int = "moonbit_uv_in_addr_pton"
///|
pub fn InAddr::pton(src : Bytes) -> InAddr raise Errno {
let dst = Ref::new(InAddr(0))
let status = uv_in_addr_pton(src, dst)
if status < 0 {
raise Errno::of_int(status)
}
dst.val
}
///|
#borrow(addr)
extern "c" fn uv_sockaddr_in6_port(addr : SockaddrIn6) -> UInt = "moonbit_uv_sockaddr_in6_port"
///|
pub fn SockaddrIn6::port(self : SockaddrIn6) -> UInt16 {
Int16::from_int(uv_sockaddr_in6_port(self).reinterpret_as_int()).reinterpret_as_uint16()
}
///|
#borrow(addr)
extern "c" fn uv_sockaddr_in6_scope_id(addr : SockaddrIn6) -> UInt = "moonbit_uv_sockaddr_in6_scope_id"
///|
pub fn SockaddrIn6::scope_id(self : SockaddrIn6) -> IfIndex {
uv_sockaddr_in6_scope_id(self)
}
///|
#valtype
struct In6Addr(UInt64, UInt64)
///|
fn init {
ignore(In6Addr(0, 0).0)
ignore(In6Addr(0, 0).1)
}
///|
pub extern "c" fn In6Addr::new(
h0 : UInt16,
h1 : UInt16,
h2 : UInt16,
h3 : UInt16,
h4 : UInt16,
h5 : UInt16,
h6 : UInt16,
h7 : UInt16,
) -> In6Addr = "moonbit_uv_in6_addr_make"
///|
#borrow(self)
pub extern "c" fn In6Addr::to_bytes(self : In6Addr) -> Bytes = "moonbit_uv_in6_addr_to_bytes"
///|
pub impl ToJson for In6Addr with to_json(self : In6Addr) -> Json {
wtf8_to_string(self.ntop()).to_json() catch {
_ => self.to_bytes().to_array().to_json()
}
}
///|
#borrow(addr)
extern "c" fn uv_sockaddr_in6_addr(addr : SockaddrIn6) -> In6Addr = "moonbit_uv_sockaddr_in6_addr"
///|
pub fn SockaddrIn6::addr(self : SockaddrIn6) -> In6Addr {
uv_sockaddr_in6_addr(self)
}
///|
#borrow(src, dst)
extern "c" fn uv_in6_addr_ntop(src : In6Addr, dst : FixedArray[Byte]) -> Int = "moonbit_uv_in6_addr_ntop"
///|
#borrow(src, dst)
extern "c" fn uv_in6_addr_pton(src : Bytes, dst : Ref[In6Addr]) -> Int = "moonbit_uv_in6_addr_pton"
///|
pub fn In6Addr::ntop(self : In6Addr) -> Bytes raise Errno {
let dst : FixedArray[Byte] = FixedArray::make(_INET6_ADDRSTRLEN, 0)
let status = uv_in6_addr_ntop(self, dst)
if status < 0 {
raise Errno::of_int(status)
}
let len = for i in 0.. In6Addr raise Errno {
let dst = Ref::new(In6Addr(0, 0))
let status = uv_in6_addr_pton(src, dst)
if status < 0 {
raise Errno::of_int(status)
}
dst.val
}
///|
struct SockaddrIn6(Bytes)
///|
pub impl ToJson for SockaddrIn6 with to_json(self : SockaddrIn6) -> Json {
{ "addr": self.addr(), "port": self.port(), "scope_id": self.scope_id() }
}
///|
extern "c" fn uv_sockaddr_in6_make() -> SockaddrIn6 = "moonbit_uv_sockaddr_in6_make"
///|
struct Sockaddr(Bytes)
///|
extern "c" fn uv_sockaddr_make() -> Sockaddr = "moonbit_uv_sockaddr_make"
///|
#borrow(addr)
extern "c" fn uv_sockaddr_family(addr : Sockaddr) -> Int = "moonbit_uv_sockaddr_family"
///|
pub impl ToJson for Sockaddr with to_json(self : Sockaddr) -> Json {
if SockaddrIn::of_sockaddr(self) is Some(self) {
self.to_json()
} else if SockaddrIn6::of_sockaddr(self) is Some(self) {
self.to_json()
} else {
{ "family": uv_sockaddr_family(self) }
}
}
///|
pub trait ToSockaddr: ToJson {
to_sockaddr(self : Self) -> Sockaddr
of_sockaddr(self : Sockaddr) -> Self?
ip_name(self : Self) -> Bytes raise Errno
}
///|
pub impl ToSockaddr for Sockaddr with to_sockaddr(self : Sockaddr) -> Sockaddr = "%identity"
///|
pub impl ToSockaddr for Sockaddr with of_sockaddr(self : Sockaddr) -> Sockaddr? {
Some(self)
}
///|
pub impl ToSockaddr for SockaddrIn with to_sockaddr(addr : SockaddrIn) -> Sockaddr = "%identity"
///|
pub impl ToSockaddr for SockaddrIn with of_sockaddr(addr : Sockaddr) -> SockaddrIn? {
if uv_sockaddr_family(addr) == _AF_INET {
Some(addr.0)
} else {
None
}
}
///|
pub impl ToSockaddr for SockaddrIn6 with to_sockaddr(addr : SockaddrIn6) -> Sockaddr = "%identity"
///|
pub impl ToSockaddr for SockaddrIn6 with of_sockaddr(addr : Sockaddr) -> SockaddrIn6? {
if uv_sockaddr_family(addr) == _AF_INET6 {
Some(addr.0)
} else {
None
}
}
///|
enum SockType {
Stream
Raw
Datagram
}
///|
pub fn SockType::stream() -> SockType {
return Stream
}
///|
pub fn SockType::raw() -> SockType {
return Raw
}
///|
#deprecated("Use SockType::datagram() instead")
pub fn SockType::dgram() -> SockType {
return Datagram
}
///|
pub fn SockType::datagram() -> SockType {
return Datagram
}
///|
extern "c" fn uv_SOCK_STREAM() -> Int = "moonbit_uv_SOCK_STREAM"
///|
let _SOCK_STREAM : Int = uv_SOCK_STREAM()
///|
extern "c" fn uv_SOCK_DGRAM() -> Int = "moonbit_uv_SOCK_DGRAM"
///|
let _SOCK_DGRAM : Int = uv_SOCK_DGRAM()
///|
extern "c" fn uv_SOCK_RAW() -> Int = "moonbit_uv_SOCK_RAW"
///|
let _SOCK_RAW : Int = uv_SOCK_RAW()
///|
fn SockType::of_int(self : Int) -> SockType raise Errno {
if self == _SOCK_STREAM {
return Stream
}
if self == _SOCK_RAW {
return Raw
}
if self == _SOCK_DGRAM {
return Datagram
}
raise EINVAL
}
///|
fn SockType::to_int(self : SockType) -> Int {
match self {
Stream => _SOCK_STREAM
Raw => _SOCK_RAW
Datagram => _SOCK_DGRAM
}
}
///|
type OsSock
///|
extern "c" fn uv_os_sock_make() -> OsSock = "moonbit_uv_os_sock_make"
///|
#borrow(sock)
extern "c" fn uv_os_sock_to_int(sock : OsSock) -> Int = "moonbit_uv_os_sock_to_int"
///|
pub fn OsSock::to_int(self : OsSock) -> Int {
uv_os_sock_to_int(self)
}
///|
#owned(sock0, sock1)
extern "c" fn uv_socketpair(
type_ : Int,
protocol : Int,
sock0 : OsSock,
flags0 : Int,
sock1 : OsSock,
flags1 : Int,
) -> Int = "moonbit_uv_socketpair"
///|
pub fn socketpair(
type_ : SockType,
protocol? : Protocol,
flags : (PipeFlags, PipeFlags),
) -> (OsSock, OsSock) raise Errno {
let protocol = match protocol {
Some(p) => p.to_int()
None => 0
}
let socks = (uv_os_sock_make(), uv_os_sock_make())
let status = uv_socketpair(
type_.to_int(),
protocol,
socks.0,
flags.0.0,
socks.1,
flags.1.0,
)
if status < 0 {
raise Errno::of_int(status)
}
return socks
}