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///|
16type FsEvent
17
18///|
19pub impl 
trait ToHandle {
  to_handle(Self) -> Handle
  of_handle(Handle) -> Self
  close(Self, (Self) -> Unit) -> Unit
  is_closing(Self) -> Bool
  loop_(Self) -> Loop
}
ToHandle
for
type FsEvent
FsEvent
with to_handle(self) = "%identity"
20 21///| 22pub impl
trait ToHandle {
  to_handle(Self) -> Handle
  of_handle(Handle) -> Self
  close(Self, (Self) -> Unit) -> Unit
  is_closing(Self) -> Bool
  loop_(Self) -> Loop
}
ToHandle
for
type FsEvent
FsEvent
with of_handle(handle :
type Handle
Handle
) ->
type FsEvent
FsEvent
= "%identity"
23 24///| 25extern "c" fn uv_fs_event_make() ->
type FsEvent
FsEvent
= "moonbit_uv_fs_event_make"
26 27///| 28extern "c" fn uv_fs_event_init(uv :
type Loop Bytes
Loop
, fs_event :
type FsEvent
FsEvent
) ->
Int
Int
= "moonbit_uv_fs_event_init"
29 30///| 31pub fn
type FsEvent
FsEvent
::
(self : Loop) -> FsEvent raise Errno
new
(
Loop
self
:
type Loop Bytes
Loop
) ->
type FsEvent
FsEvent
raise
type! Errno Status
Errno
{
32 let
FsEvent
fs_event
=
() -> FsEvent
uv_fs_event_make
()
33 let
Int
status
=
(uv : Loop, fs_event : FsEvent) -> Int
uv_fs_event_init
(
Loop
self
,
FsEvent
fs_event
)
34 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
35 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
36 } 37 return
FsEvent
fs_event
38} 39 40///| 41pub enum FsEventType { 42
FsEventType
Rename
= 1
43
FsEventType
Change
= 2
44} derive(
trait Show {
  output(Self, &Logger) -> Unit
  to_string(Self) -> String
}

Trait for types that can be converted to String

Show
)
45 46///| 47pub impl
trait ToJson {
  to_json(Self) -> Json
}

Trait for types that can be converted to Json

ToJson
for
enum FsEventType {
  Rename
  Change
}
FsEventType
with
(self : FsEventType) -> Json
to_json
(
FsEventType
self
) {
48 match
FsEventType
self
{
49
FsEventType
Rename
=> "Rename"
50
FsEventType
Change
=> "Change"
51 } 52} 53 54///| 55const
Int
UV_RENAME
= 1
56 57///| 58const
Int
UV_CHANGE
= 2
59 60///| 61extern "c" fn uv_fs_event_start( 62 fs_event :
type FsEvent
FsEvent
,
63 cb : (
type FsEvent
FsEvent
,
type @c.Pointer[_]
@c.Pointer
[
Byte
Byte
],
Int
Int
,
Int
Int
) ->
Unit
Unit
,
64 path :
Bytes
Bytes
,
65 flags :
Int
Int
66) ->
Int
Int
= "moonbit_uv_fs_event_start"
67 68///| 69type FsEventFlags
Int
Int
70 71///| 72const
Int
UV_FS_EVENT_RECURSIVE
= 4
73 74///| 75pub fn
type FsEventFlags Int
FsEventFlags
::
(recursive~ : Bool = ..) -> FsEventFlags
new
(
Bool
recursive
~ :
Bool
Bool
= false) ->
type FsEventFlags Int
FsEventFlags
{
76 let mut
Int
flags
= 0
77 if
Bool
recursive
{
78
Int
flags
=
Int
flags
(Int, Int) -> Int
|
Int
UV_FS_EVENT_RECURSIVE
79 } 80 return
Int
flags
81} 82 83///| 84pub fn[ToNtbs :
trait ToNtbs {
  to_ntbs(Self) -> Bytes
}

Convertible to null-terminated byte strings (NTBS).

ToNtbs
]
type FsEvent
FsEvent
::
(self : FsEvent, path : ToNtbs, flags : FsEventFlags, event_cb : (FsEvent, String?, Array[FsEventType]) -> Unit, error_cb : (FsEvent, String?, Errno) -> Unit) -> Unit raise Errno
start
(
85
FsEvent
self
:
type FsEvent
FsEvent
,
86
ToNtbs
path
:

type parameter ToNtbs

ToNtbs
,
87
FsEventFlags
flags
:
type FsEventFlags Int
FsEventFlags
,
88
(FsEvent, String?, Array[FsEventType]) -> Unit
event_cb
: (
type FsEvent
FsEvent
,
String
String
?,
type Array[T]

An Array is a collection of values that supports random access and can grow in size.

Array
[
enum FsEventType {
  Rename
  Change
}
FsEventType
]) ->
Unit
Unit
,
89
(FsEvent, String?, Errno) -> Unit
error_cb
: (
type FsEvent
FsEvent
,
String
String
?,
type! Errno Status
Errno
) ->
Unit
Unit
90) ->
Unit
Unit
raise
type! Errno Status
Errno
{
91 fn
(FsEvent, @c.Pointer[Byte], Int, Int) -> Unit
uv_cb
(
92
FsEvent
fs_event
:
type FsEvent
FsEvent
,
93
@c.Pointer[Byte]
filename
:
type @c.Pointer[_]
@c.Pointer
[
Byte
Byte
],
94
Int
events
:
Int
Int
,
95
Int
status
:
Int
Int
96 ) { 97 let
String?
filename
= if
@c.Pointer[Byte]
filename
.
(self : @c.Pointer[Byte]) -> Bool
is_null
() {
98
String?
None
99 } else { 100 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
()
101 for
Int
i
= 0;
@c.Pointer[Byte]
filename
(@c.Pointer[Byte], Int) -> Byte
[
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 {
102
@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
(
@c.Pointer[Byte]
filename
(@c.Pointer[Byte], Int) -> Byte
[
i])
103 } 104
(String) -> String?
Some
(
(input : @bytes.View, encoding~ : @encoding.Encoding) -> String
@encoding.decode_lossy
(
@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
(),
@encoding.Encoding
encoding
=
@encoding.Encoding
UTF8
))
105 } 106 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
107
(FsEvent, String?, Errno) -> Unit
error_cb
(
FsEvent
fs_event
,
String?
filename
,
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
))
108 } else { 109 let
Array[FsEventType]
event_types
= []
110 if (
Int
events
(Int, Int) -> Int
&
Int
UV_RENAME
)
(x : Int, y : Int) -> Bool
!=
0 {
111
Array[FsEventType]
event_types
.
(self : Array[FsEventType], value : FsEventType) -> Unit

Adds an element to the end of the array.

If the array is at capacity, it will be reallocated.

Example

  let v = []
  v.push(3)
push
(
FsEventType
Rename
)
112 } 113 if (
Int
events
(Int, Int) -> Int
&
Int
UV_CHANGE
)
(x : Int, y : Int) -> Bool
!=
0 {
114
Array[FsEventType]
event_types
.
(self : Array[FsEventType], value : FsEventType) -> Unit

Adds an element to the end of the array.

If the array is at capacity, it will be reallocated.

Example

  let v = []
  v.push(3)
push
(
FsEventType
Change
)
115 } 116
(FsEvent, String?, Array[FsEventType]) -> Unit
event_cb
(
FsEvent
fs_event
,
String?
filename
,
Array[FsEventType]
event_types
)
117 } 118 } 119 120 let
Bytes
path
=

type parameter

ToNtbs
::
(ToNtbs) -> Bytes
to_ntbs
(
ToNtbs
path
)
121 let
Int
status
=
(fs_event : FsEvent, cb : (FsEvent, @c.Pointer[Byte], Int, Int) -> Unit, path : Bytes, flags : Int) -> Int
uv_fs_event_start
(
FsEvent
self
,
(FsEvent, @c.Pointer[Byte], Int, Int) -> Unit
uv_cb
,
Bytes
path
,
FsEventFlags
flags
.
(self : FsEventFlags) -> Int

Convert newtype to its underlying type, automatically derived.

inner
())
122 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
123 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
124 } 125} 126 127///| 128extern "c" fn uv_fs_event_stop(fs_event :
type FsEvent
FsEvent
) ->
Int
Int
= "moonbit_uv_fs_event_stop"
129 130///| 131pub fn
type FsEvent
FsEvent
::
(self : FsEvent) -> Unit raise Errno
stop
(
FsEvent
self
:
type FsEvent
FsEvent
) ->
Unit
Unit
raise
type! Errno Status
Errno
{
132 let
Int
status
=
(fs_event : FsEvent) -> Int
uv_fs_event_stop
(
FsEvent
self
)
133 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
134 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
135 } 136} 137 138///| 139extern "c" fn uv_fs_event_getpath( 140 fs_event :
type FsEvent
FsEvent
,
141 buffer :
Bytes
Bytes
,
142 length :
type FixedArray[A]
FixedArray
[
Int
Int
]
143) ->
Int
Int
= "moonbit_uv_fs_event_getpath"
144 145///| 146pub fn
type FsEvent
FsEvent
::
(self : FsEvent) -> String raise Errno
get_path
(
FsEvent
self
:
type FsEvent
FsEvent
) ->
String
String
raise
type! Errno Status
Errno
{
147 let mut
Bytes
buffer
=
(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
(64, 0)
148 let
FixedArray[Int]
length
:
type FixedArray[A]
FixedArray
[
Int
Int
] = [
Bytes
buffer
.
(self : Bytes) -> Int

Returns the number of bytes in a byte sequence.

Parameters:

  • bytes : The byte sequence whose length is to be determined.

Returns an integer representing the length (number of bytes) of the sequence.

Example:

  let bytes = b"\x01\x02\x03"
  inspect(bytes.length(), content="3")
  let empty = b""
  inspect(empty.length(), content="0")
length
()]
149 let mut
Int
status
=
(fs_event : FsEvent, buffer : Bytes, length : FixedArray[Int]) -> Int
uv_fs_event_getpath
(
FsEvent
self
,
Bytes
buffer
,
FixedArray[Int]
length
)
150 if
Int
status
(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
_ENOBUFS
{
151
Bytes
buffer
=
(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
(
FixedArray[Int]
length
[0], 0)
152
Int
status
=
(fs_event : FsEvent, buffer : Bytes, length : FixedArray[Int]) -> Int
uv_fs_event_getpath
(
FsEvent
self
,
Bytes
buffer
,
FixedArray[Int]
length
)
153 } 154 if
Int
status
(self_ : Int, other : Int) -> Bool
<
0 {
155 raise
type! Errno Status
Errno
::
(errno : Int) -> Errno
of_int
(
Int
status
)
156 } 157
(input : @bytes.View, encoding~ : @encoding.Encoding) -> String
@encoding.decode_lossy
(
Bytes
buffer
,
@encoding.Encoding
encoding
=
@encoding.Encoding
UTF8
)
158} 159