1// Copyright 2025 International Digital Economy Academy
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15///|
16pub impl 
trait ToSockaddr {
  to_sockaddr(self : Self) -> Sockaddr
  ip_name(self : Self) -> String raise Errno
}
ToSockaddr
for
type Sockaddr Bytes
Sockaddr
with
(self : Sockaddr) -> String raise Errno
ip_name
(
Sockaddr
self
:
type Sockaddr Bytes
Sockaddr
) ->
String
String
raise
type! Errno Status
Errno
{
17 let
Sockaddr
self
=
Sockaddr
self
.
(self : Sockaddr) -> Sockaddr
to_sockaddr
()
18 let
Bytes
bytes
=
(Int, Byte) -> Bytes
Bytes::
(len : Int, init : Byte) -> Bytes

Creates a new byte sequence of the specified length, where each byte is initialized to the given value. Returns an empty byte sequence if the length is negative.

Parameters:

  • length : The length of the byte sequence to create. Must be non-negative.
  • initial_value : The byte value used to initialize each position in the sequence.

Example:

  let bytes = Bytes::make(3, b'\xFF')
  inspect(bytes, content=
  #|b"\xff\xff\xff"
)
  let empty = Bytes::make(0, b'\x00')
  inspect(empty, content="b\"\"")
make
(
Int
_IF_NAMESIZE
, 0)
19 let
Int
status
=
(src : Sockaddr, dst : Bytes) -> Int
uv_ip_name
(
Sockaddr
self
,
Bytes
bytes
)
20 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
21 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
22 } 23 let
@buffer.T
buffer
=
(size_hint~ : Int = ..) -> @buffer.T

Creates a new extensible buffer with specified initial capacity. If the initial capacity is less than 1, the buffer will be initialized with capacity 1.

Parameters:

  • size_hint : Initial capacity of the buffer in bytes. Defaults to 0.

Returns a new buffer of type T.

Example:

  let buf = @buffer.new(size_hint=10)
  inspect(buf.length(), content="0")
  buf.write_string("test")
  inspect(buf.length(), content="8")
@buffer.new
()
24 for
Int
i
= 0;
Bytes
bytes
(Bytes, Int) -> Byte

Retrieves a byte at the specified index from a byte sequence.

Parameters:

  • bytes : The byte sequence to access.
  • index : The position in the byte sequence from which to retrieve the byte.

Returns a byte value from the specified position in the sequence.

Throws a panic if the index is negative or greater than or equal to the length of the byte sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes[1], content="b'\\x02'")
[
i]
(x : Byte, y : Byte) -> Bool
!=
0;
Int
i
=
Int
i
(self : Int, other : Int) -> Int

Adds two 32-bit signed integers. Performs two's complement arithmetic, which means the operation will wrap around if the result exceeds the range of a 32-bit integer.

Parameters:

  • self : The first integer operand.
  • other : The second integer operand.

Returns a new integer that is the sum of the two operands. If the mathematical sum exceeds the range of a 32-bit integer (-2,147,483,648 to 2,147,483,647), the result wraps around according to two's complement rules.

Example:

  inspect(42 + 1, content="43")
  inspect(2147483647 + 1, content="-2147483648") // Overflow wraps around to minimum value
+
1 {
25
@buffer.T
buffer
.
(self : @buffer.T, value : Byte) -> Unit

Writes a single byte to the end of the buffer. The buffer will automatically grow if necessary to accommodate the new byte.

Parameters:

  • buffer : The buffer to write to.
  • byte : The byte value to be written.

Example:

  let buf = @buffer.new()
  buf.write_byte(b'\x41')
  inspect(buf.contents(), content="b\"\\x41\"")
write_byte
(
Bytes
bytes
(Bytes, Int) -> Byte

Retrieves a byte at the specified index from a byte sequence.

Parameters:

  • bytes : The byte sequence to access.
  • index : The position in the byte sequence from which to retrieve the byte.

Returns a byte value from the specified position in the sequence.

Throws a panic if the index is negative or greater than or equal to the length of the byte sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes[1], content="b'\\x02'")
[
i])
26 } 27
(encoding~ : @encoding.Encoding, input : @bytes.View) -> String
@encoding.decode_lossy
(
@encoding.Encoding
encoding
=
@encoding.Encoding
UTF8
,
@buffer.T
buffer
.
(self : @buffer.T) -> Bytes

Returns a copy of the buffer's content as a sequence of bytes.

Parameters:

  • buffer : The buffer to read from.

Returns a Bytes object containing all bytes written to the buffer.

Example:

  let buf = @buffer.new()
  buf.write_string("Test")
  inspect(
    buf.contents(),
    content=
      #|b"\x54\x00\x65\x00\x73\x00\x74\x00"
    ,
  )
contents
())
28} 29 30///| 31#borrow(ip, addr) 32extern "c" fn uv_ip4_addr(ip :
Bytes
Bytes
, port :
Int
Int
, addr :
type SockaddrIn Bytes
SockaddrIn
) ->
Int
Int
= "moonbit_uv_ip4_addr"
33 34///| 35/// Creates an IPv4 socket address structure from an IP address and port number. 36/// 37/// Parameters: 38/// 39/// * `ip` : The IPv4 address as a null-terminated byte string (e.g., 40/// "127.0.0.1"). 41/// * `port` : The port number for the socket address. 42/// 43/// Returns a `SockaddrIn` structure representing the IPv4 socket address that 44/// can be used with TCP operations like binding or connecting. 45/// 46/// Example: 47/// 48/// ```moonbit 49/// let addr = @uv.ip4_addr("127.0.0.1", 8080) 50/// println(addr.ip_name()) 51/// ``` 52pub fn[Ntbs :
trait ToNtbs {
  to_ntbs(Self) -> Bytes
}

Convertible to null-terminated byte strings (NTBS).

ToNtbs
]
(ip : Ntbs, port : Int) -> SockaddrIn raise Errno

Creates an IPv4 socket address structure from an IP address and port number.

Parameters:

  • ip : The IPv4 address as a null-terminated byte string (e.g., "127.0.0.1").
  • port : The port number for the socket address.

Returns a SockaddrIn structure representing the IPv4 socket address that can be used with TCP operations like binding or connecting.

Example:

let addr = @uv.ip4_addr("127.0.0.1", 8080)
println(addr.ip_name())
ip4_addr
(
Ntbs
ip
:

type parameter Ntbs

Ntbs
,
Int
port
:
Int
Int
) ->
type SockaddrIn Bytes
SockaddrIn
raise
type! Errno Status
Errno
{
53 let
Bytes
ip
=
Ntbs
ip
.
(Ntbs) -> Bytes
to_ntbs
()
54 let
SockaddrIn
addr
=
() -> SockaddrIn
uv_sockaddr_in_make
()
55 let
Int
status
=
(ip : Bytes, port : Int, addr : SockaddrIn) -> Int
uv_ip4_addr
(
Bytes
ip
,
Int
port
,
SockaddrIn
addr
)
56 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
57 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
58 } 59
SockaddrIn
addr
60} 61 62///| 63#borrow(addr, dst) 64extern "c" fn uv_ip4_name(addr :
type SockaddrIn Bytes
SockaddrIn
, dst :
Bytes
Bytes
) ->
Int
Int
= "moonbit_uv_ip4_name"
65 66///| 67pub impl
trait ToSockaddr {
  to_sockaddr(self : Self) -> Sockaddr
  ip_name(self : Self) -> String raise Errno
}
ToSockaddr
for
type SockaddrIn Bytes
SockaddrIn
with
(self : SockaddrIn) -> String raise Errno
ip_name
(
SockaddrIn
self
:
type SockaddrIn Bytes
SockaddrIn
) ->
String
String
raise
type! Errno Status
Errno
{
68 let
Bytes
bytes
=
(Int, Byte) -> Bytes
Bytes::
(len : Int, init : Byte) -> Bytes

Creates a new byte sequence of the specified length, where each byte is initialized to the given value. Returns an empty byte sequence if the length is negative.

Parameters:

  • length : The length of the byte sequence to create. Must be non-negative.
  • initial_value : The byte value used to initialize each position in the sequence.

Example:

  let bytes = Bytes::make(3, b'\xFF')
  inspect(bytes, content=
  #|b"\xff\xff\xff"
)
  let empty = Bytes::make(0, b'\x00')
  inspect(empty, content="b\"\"")
make
(
Int
_IF_NAMESIZE
, 0)
69 let
Int
status
=
(addr : SockaddrIn, dst : Bytes) -> Int
uv_ip4_name
(
SockaddrIn
self
,
Bytes
bytes
)
70 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
71 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
72 } 73 let
@buffer.T
buffer
=
(size_hint~ : Int = ..) -> @buffer.T

Creates a new extensible buffer with specified initial capacity. If the initial capacity is less than 1, the buffer will be initialized with capacity 1.

Parameters:

  • size_hint : Initial capacity of the buffer in bytes. Defaults to 0.

Returns a new buffer of type T.

Example:

  let buf = @buffer.new(size_hint=10)
  inspect(buf.length(), content="0")
  buf.write_string("test")
  inspect(buf.length(), content="8")
@buffer.new
()
74 for
Int
i
= 0;
Bytes
bytes
(Bytes, Int) -> Byte

Retrieves a byte at the specified index from a byte sequence.

Parameters:

  • bytes : The byte sequence to access.
  • index : The position in the byte sequence from which to retrieve the byte.

Returns a byte value from the specified position in the sequence.

Throws a panic if the index is negative or greater than or equal to the length of the byte sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes[1], content="b'\\x02'")
[
i]
(x : Byte, y : Byte) -> Bool
!=
0;
Int
i
=
Int
i
(self : Int, other : Int) -> Int

Adds two 32-bit signed integers. Performs two's complement arithmetic, which means the operation will wrap around if the result exceeds the range of a 32-bit integer.

Parameters:

  • self : The first integer operand.
  • other : The second integer operand.

Returns a new integer that is the sum of the two operands. If the mathematical sum exceeds the range of a 32-bit integer (-2,147,483,648 to 2,147,483,647), the result wraps around according to two's complement rules.

Example:

  inspect(42 + 1, content="43")
  inspect(2147483647 + 1, content="-2147483648") // Overflow wraps around to minimum value
+
1 {
75
@buffer.T
buffer
.
(self : @buffer.T, value : Byte) -> Unit

Writes a single byte to the end of the buffer. The buffer will automatically grow if necessary to accommodate the new byte.

Parameters:

  • buffer : The buffer to write to.
  • byte : The byte value to be written.

Example:

  let buf = @buffer.new()
  buf.write_byte(b'\x41')
  inspect(buf.contents(), content="b\"\\x41\"")
write_byte
(
Bytes
bytes
(Bytes, Int) -> Byte

Retrieves a byte at the specified index from a byte sequence.

Parameters:

  • bytes : The byte sequence to access.
  • index : The position in the byte sequence from which to retrieve the byte.

Returns a byte value from the specified position in the sequence.

Throws a panic if the index is negative or greater than or equal to the length of the byte sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes[1], content="b'\\x02'")
[
i])
76 } 77
(encoding~ : @encoding.Encoding, input : @bytes.View) -> String
@encoding.decode_lossy
(
@encoding.Encoding
encoding
=
@encoding.Encoding
UTF8
,
@buffer.T
buffer
.
(self : @buffer.T) -> Bytes

Returns a copy of the buffer's content as a sequence of bytes.

Parameters:

  • buffer : The buffer to read from.

Returns a Bytes object containing all bytes written to the buffer.

Example:

  let buf = @buffer.new()
  buf.write_string("Test")
  inspect(
    buf.contents(),
    content=
      #|b"\x54\x00\x65\x00\x73\x00\x74\x00"
    ,
  )
contents
())
78} 79 80///| 81#borrow(ip, addr) 82extern "c" fn uv_ip6_addr(ip :
Bytes
Bytes
, port :
Int
Int
, addr :
type SockaddrIn6 Bytes
SockaddrIn6
) ->
Int
Int
= "moonbit_uv_ip6_addr"
83 84///| 85pub fn[Ntbs :
trait ToNtbs {
  to_ntbs(Self) -> Bytes
}

Convertible to null-terminated byte strings (NTBS).

ToNtbs
]
(ip : Ntbs, port : Int) -> SockaddrIn6 raise Errno
ip6_addr
(
86
Ntbs
ip
:

type parameter Ntbs

Ntbs
,
87
Int
port
:
Int
Int
88) ->
type SockaddrIn6 Bytes
SockaddrIn6
raise
type! Errno Status
Errno
{
89 let
Bytes
ip
=
Ntbs
ip
.
(Ntbs) -> Bytes
to_ntbs
()
90 let
SockaddrIn6
addr
=
() -> SockaddrIn6
uv_sockaddr_in6_make
()
91 let
Int
status
=
(ip : Bytes, port : Int, addr : SockaddrIn6) -> Int
uv_ip6_addr
(
Bytes
ip
,
Int
port
,
SockaddrIn6
addr
)
92 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
93 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
94 } 95
SockaddrIn6
addr
96} 97 98///| 99#borrow(addr, dst) 100extern "c" fn uv_ip6_name(addr :
type SockaddrIn6 Bytes
SockaddrIn6
, dst :
Bytes
Bytes
) ->
Int
Int
= "moonbit_uv_ip6_name"
101 102///| 103pub impl
trait ToSockaddr {
  to_sockaddr(self : Self) -> Sockaddr
  ip_name(self : Self) -> String raise Errno
}
ToSockaddr
for
type SockaddrIn6 Bytes
SockaddrIn6
with
(self : SockaddrIn6) -> String raise Errno
ip_name
(
SockaddrIn6
self
:
type SockaddrIn6 Bytes
SockaddrIn6
) ->
String
String
raise
type! Errno Status
Errno
{
104 let
Bytes
bytes
=
(Int, Byte) -> Bytes
Bytes::
(len : Int, init : Byte) -> Bytes

Creates a new byte sequence of the specified length, where each byte is initialized to the given value. Returns an empty byte sequence if the length is negative.

Parameters:

  • length : The length of the byte sequence to create. Must be non-negative.
  • initial_value : The byte value used to initialize each position in the sequence.

Example:

  let bytes = Bytes::make(3, b'\xFF')
  inspect(bytes, content=
  #|b"\xff\xff\xff"
)
  let empty = Bytes::make(0, b'\x00')
  inspect(empty, content="b\"\"")
make
(
Int
_IF_NAMESIZE
, 0)
105 let
Int
status
=
(addr : SockaddrIn6, dst : Bytes) -> Int
uv_ip6_name
(
SockaddrIn6
self
,
Bytes
bytes
)
106 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
107 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
108 } 109 let
@buffer.T
buffer
=
(size_hint~ : Int = ..) -> @buffer.T

Creates a new extensible buffer with specified initial capacity. If the initial capacity is less than 1, the buffer will be initialized with capacity 1.

Parameters:

  • size_hint : Initial capacity of the buffer in bytes. Defaults to 0.

Returns a new buffer of type T.

Example:

  let buf = @buffer.new(size_hint=10)
  inspect(buf.length(), content="0")
  buf.write_string("test")
  inspect(buf.length(), content="8")
@buffer.new
()
110 for
Int
i
= 0;
Bytes
bytes
(Bytes, Int) -> Byte

Retrieves a byte at the specified index from a byte sequence.

Parameters:

  • bytes : The byte sequence to access.
  • index : The position in the byte sequence from which to retrieve the byte.

Returns a byte value from the specified position in the sequence.

Throws a panic if the index is negative or greater than or equal to the length of the byte sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes[1], content="b'\\x02'")
[
i]
(x : Byte, y : Byte) -> Bool
!=
0;
Int
i
=
Int
i
(self : Int, other : Int) -> Int

Adds two 32-bit signed integers. Performs two's complement arithmetic, which means the operation will wrap around if the result exceeds the range of a 32-bit integer.

Parameters:

  • self : The first integer operand.
  • other : The second integer operand.

Returns a new integer that is the sum of the two operands. If the mathematical sum exceeds the range of a 32-bit integer (-2,147,483,648 to 2,147,483,647), the result wraps around according to two's complement rules.

Example:

  inspect(42 + 1, content="43")
  inspect(2147483647 + 1, content="-2147483648") // Overflow wraps around to minimum value
+
1 {
111
@buffer.T
buffer
.
(self : @buffer.T, value : Byte) -> Unit

Writes a single byte to the end of the buffer. The buffer will automatically grow if necessary to accommodate the new byte.

Parameters:

  • buffer : The buffer to write to.
  • byte : The byte value to be written.

Example:

  let buf = @buffer.new()
  buf.write_byte(b'\x41')
  inspect(buf.contents(), content="b\"\\x41\"")
write_byte
(
Bytes
bytes
(Bytes, Int) -> Byte

Retrieves a byte at the specified index from a byte sequence.

Parameters:

  • bytes : The byte sequence to access.
  • index : The position in the byte sequence from which to retrieve the byte.

Returns a byte value from the specified position in the sequence.

Throws a panic if the index is negative or greater than or equal to the length of the byte sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes[1], content="b'\\x02'")
[
i])
112 } 113
(encoding~ : @encoding.Encoding, input : @bytes.View) -> String
@encoding.decode_lossy
(
@encoding.Encoding
encoding
=
@encoding.Encoding
UTF8
,
@buffer.T
buffer
.
(self : @buffer.T) -> Bytes

Returns a copy of the buffer's content as a sequence of bytes.

Parameters:

  • buffer : The buffer to read from.

Returns a Bytes object containing all bytes written to the buffer.

Example:

  let buf = @buffer.new()
  buf.write_string("Test")
  inspect(
    buf.contents(),
    content=
      #|b"\x54\x00\x65\x00\x73\x00\x74\x00"
    ,
  )
contents
())
114} 115 116///| 117pub enum Protocol { 118
Protocol
Tcp
119
Protocol
Udp
120} derive(
trait Show {
  output(Self, &Logger) -> Unit
  to_string(Self) -> String
}

Trait for types that can be converted to String

Show
)
121 122///| 123pub fn
enum Protocol {
  Tcp
  Udp
}
Protocol
::
() -> Protocol
tcp
() ->
enum Protocol {
  Tcp
  Udp
}
Protocol
{
124 return
Protocol
Tcp
125} 126 127///| 128pub fn
enum Protocol {
  Tcp
  Udp
}
Protocol
::
() -> Protocol
udp
() ->
enum Protocol {
  Tcp
  Udp
}
Protocol
{
129 return
Protocol
Udp
130} 131 132///| 133extern "c" fn uv_IPPROTO_UDP() ->
Int
Int
= "moonbit_uv_IPPROTO_UDP"
134 135///| 136let
Int
_IPPROTO_UDP
:
Int
Int
=
() -> Int
uv_IPPROTO_UDP
()
137 138///| 139extern "c" fn uv_IPPROTO_TCP() ->
Int
Int
= "moonbit_uv_IPPROTO_TCP"
140 141///| 142let
Int
_IPPROTO_TCP
:
Int
Int
=
() -> Int
uv_IPPROTO_TCP
()
143 144///| 145fn
enum Protocol {
  Tcp
  Udp
}
Protocol
::
(self : Int) -> Protocol raise Errno
of_int
(
Int
self
:
Int
Int
) ->
enum Protocol {
  Tcp
  Udp
}
Protocol
raise
type! Errno Status
Errno
{
146 if
Int
self
(self : Int, other : Int) -> Bool

Compares two integers for equality.

Parameters:

  • self : The first integer to compare.
  • other : The second integer to compare.

Returns true if both integers have the same value, false otherwise.

Example:

  inspect(42 == 42, content="true")
  inspect(42 == -42, content="false")
==
Int
_IPPROTO_TCP
{
147 return
Protocol
Tcp
148 } 149 if
Int
self
(self : Int, other : Int) -> Bool

Compares two integers for equality.

Parameters:

  • self : The first integer to compare.
  • other : The second integer to compare.

Returns true if both integers have the same value, false otherwise.

Example:

  inspect(42 == 42, content="true")
  inspect(42 == -42, content="false")
==
Int
_IPPROTO_UDP
{
150 return
Protocol
Udp
151 } 152 raise
(Status) -> Errno
Errno
(
Status
EINVAL
)
153} 154 155///| 156fn
enum Protocol {
  Tcp
  Udp
}
Protocol
::
(self : Protocol) -> Int
to_int
(
Protocol
self
:
enum Protocol {
  Tcp
  Udp
}
Protocol
) ->
Int
Int
{
157 match
Protocol
self
{
158
Protocol
Tcp
=>
Int
_IPPROTO_TCP
159
Protocol
Udp
=>
Int
_IPPROTO_UDP
160 } 161} 162 163///| 164#borrow(src, dst) 165extern "c" fn uv_ip_name(src :
type Sockaddr Bytes
Sockaddr
, dst :
Bytes
Bytes
) ->
Int
Int
= "moonbit_uv_ip_name"
166