///|
#borrow(path)
extern "C" fn native_backend_watch(
path : Bytes,
use_polling : Int,
interval : Int,
) -> Int = "chokidar_backend_watch"
///|
extern "C" fn native_backend_close(id : Int) -> Unit = "chokidar_backend_close"
///|
extern "C" fn native_backend_event_count() -> Int = "chokidar_backend_event_count"
///|
extern "C" fn native_backend_event_name(index : Int) -> Bytes = "chokidar_backend_event_name"
///|
extern "C" fn native_backend_watched_path(index : Int) -> Bytes = "chokidar_backend_watched_path"
///|
extern "C" fn native_backend_event_path(index : Int) -> Bytes = "chokidar_backend_event_path"
///|
extern "C" fn native_backend_platform() -> Bytes = "chokidar_backend_platform"
///|
extern "C" fn native_backend_clear_events() -> Unit = "chokidar_backend_clear_events"
///|
#borrow(name)
extern "C" fn native_getenv_valid(name : Bytes) -> Int = "chokidar_getenv_valid"
///|
#borrow(name)
extern "C" fn native_getenv_value(name : Bytes) -> Bytes = "chokidar_getenv_value"
///|
fn chokidar_getenv(name : String) -> String? {
let name_bytes = backend_string_to_utf8_bytes(name)
if native_getenv_valid(name_bytes) == 0 {
None
} else {
Some(backend_bytes_to_string(native_getenv_value(name_bytes)))
}
}
///|
fn backend_string_to_utf8_bytes(value : String) -> Bytes {
let byte_length = value
.iter()
.fold(init=0, (length, char) => {
let code = char.to_int()
if code < 0x80 {
length + 1
} else if code < 0x800 {
length + 2
} else if code < 0x10000 {
length + 3
} else {
length + 4
}
})
let bytes = FixedArray::make(byte_length, b'\x00')
ignore(
value
.iter()
.fold(init=0, (offset, char) => offset + bytes.set_utf8_char(offset, char)),
)
backend_fixed_byte_array_to_bytes(bytes)
}
///|
fn backend_fixed_byte_array_to_bytes(bytes : FixedArray[Byte]) -> Bytes = "%identity"
///|
fn backend_bytes_to_string(value : Bytes) -> String {
// Native path bytes become public MoonBit path strings; invalid UTF-8 is replaced.
@utf8.decode_lossy(value)
}
///|
fn backend_watch(
path : String,
options : Options,
) -> BackendHandle raise ChokidarError {
let id = native_backend_watch(
backend_string_to_utf8_bytes(path),
if options.use_polling {
1
} else {
0
},
options.interval,
)
guard id >= 0 else { raise ChokidarError("failed to start backend watcher") }
{ id, }
}
///|
fn backend_close(handle : BackendHandle) -> Unit {
native_backend_close(handle.id)
}
///|
fn backend_drain_events() -> Array[RawEvent] {
let count = native_backend_event_count()
let events : Array[RawEvent] = []
for index in 0..