///|
fn null_terminated_path(path : String) -> Bytes {
let encoded = @utf8.encode(path)
Bytes::makei(encoded.length() + 1, index => {
if index < encoded.length() {
encoded[index]
} else {
b'\x00'
}
})
}
///|
#borrow(temporary, target)
extern "C" fn atomic_replace_ffi(temporary : Bytes, target : Bytes) -> Int = "moonsearch_atomic_replace"
///|
#borrow(path)
extern "C" fn sync_file_ffi(path : Bytes) -> Int = "moonsearch_sync_file"
///|
#borrow(path)
extern "C" fn try_lock_ffi(path : Bytes) -> Int64 = "moonsearch_try_lock"
///|
#borrow(path)
extern "C" fn release_lock_ffi(path : Bytes, token : Int64) -> Int = "moonsearch_release_lock"
///|
fn platform_atomic_replace(
temporary : String,
target : String,
) -> Unit raise PersistenceError {
guard atomic_replace_ffi(
null_terminated_path(temporary),
null_terminated_path(target),
) ==
0 else {
raise PersistenceError::Io("atomic replace failed")
}
}
///|
fn platform_sync_file(path : String) -> Unit raise PersistenceError {
guard sync_file_ffi(null_terminated_path(path)) == 0 else {
raise PersistenceError::Io("file sync failed: \{path}")
}
}
///|
fn platform_try_acquire_lock(path : String) -> Int64? raise PersistenceError {
match try_lock_ffi(null_terminated_path(path)) {
-1L => None
-2L => raise PersistenceError::Io("writer lock creation failed")
token => Some(token)
}
}
///|
fn platform_release_lock(
path : String,
token : Int64,
) -> Unit raise PersistenceError {
match release_lock_ffi(null_terminated_path(path), token) {
0 => ()
_ => raise PersistenceError::Io("writer lock creation failed")
}
}
///|
fn platform_directory_capabilities() -> DirectoryCapabilities {
{
atomic_replace: true,
durable_sync: true,
exclusive_lock: true,
read_only_mapping: false,
}
}