use std::ffi::CString;
use std::os::raw::{c_char, c_int};
#[repr(C)]
pub struct RayBytes {
pub data: *const c_char,
pub len: usize,
}
extern "C" {
pub fn ray_init(
address: *const c_char,
local_mode: c_int,
node_ip: *const c_char,
code_search_path: *const c_char,
runtime_env_json: *const c_char,
log_dir: *const c_char,
) -> c_int;
pub fn ray_is_initialized() -> bool;
pub fn ray_shutdown();
pub fn ray_put(data: *const c_char, len: usize) -> RayBytes;
pub fn ray_get(id_data: *const c_char, id_len: usize, timeout_ms: c_int) -> RayBytes;
pub fn ray_wait(
ids: *const RayBytes,
count: usize,
num_objects: c_int,
timeout_ms: c_int,
) -> *mut bool;
pub fn ray_task_call(
func_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
is_ref: *const bool,
) -> RayBytes;
pub fn ray_task_call_with_resources(
func_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
is_ref: *const bool,
resources_json: *const c_char,
) -> RayBytes;
pub fn ray_task_call_python(
module_name: *const c_char,
function_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
is_ref: *const bool,
) -> RayBytes;
pub fn ray_actor_create(
func_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
) -> RayBytes;
pub fn ray_actor_create_with_resources(
func_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
resources_json: *const c_char,
) -> RayBytes;
pub fn ray_actor_create_python(
module_name: *const c_char,
class_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
) -> RayBytes;
pub fn ray_actor_call(
actor_id_data: *const c_char,
actor_id_len: usize,
func_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
) -> RayBytes;
pub fn ray_actor_call_python(
actor_id_data: *const c_char,
actor_id_len: usize,
method_name: *const c_char,
args: *const RayBytes,
arg_count: usize,
is_ref: *const bool,
) -> RayBytes;
pub fn ray_actor_kill(actor_id_data: *const c_char, actor_id_len: usize, no_restart: bool);
pub fn ray_placement_group_create(
name: *const c_char,
bundles_json: *const c_char,
strategy: c_int,
) -> RayBytes;
pub fn ray_placement_group_remove(group_id_data: *const c_char, group_id_len: usize);
pub fn ray_register_function(
func_name: *const c_char,
callback: extern "C" fn(args: *const RayBytes, arg_count: usize) -> RayBytes,
);
pub fn ray_register_member_function(
func_name: *const c_char,
callback: extern "C" fn(
actor_ptr: u64,
args: *const RayBytes,
arg_count: usize,
) -> RayBytes,
);
pub fn ray_was_current_actor_restarted() -> bool;
pub fn ray_get_namespace() -> RayBytes;
pub fn ray_get_actor(name: *const c_char, ray_namespace: *const c_char) -> RayBytes;
pub fn ray_cancel(id_data: *const c_char, id_len: usize, force_kill: bool, recursive: bool) -> c_int;
pub fn ray_get_many(ids: *const RayBytes, count: usize, timeout_ms: c_int) -> *mut RayBytes;
pub fn ray_free_bytes_array(array: *mut RayBytes, count: usize);
pub fn ray_async_get_start(id_data: *const c_char, id_len: usize) -> *mut std::ffi::c_void;
pub fn ray_async_get_fd(handle: *const std::ffi::c_void) -> c_int;
pub fn ray_async_get_is_ready(handle: *const std::ffi::c_void) -> c_int;
pub fn ray_async_get_result(handle: *const std::ffi::c_void) -> RayBytes;
pub fn ray_async_get_destroy(handle: *mut std::ffi::c_void);
pub fn ray_free_bytes(ptr: *mut RayBytes);
pub fn ray_free_bools(ptr: *mut bool);
pub fn ray_last_error() -> *const c_char;
pub fn ray_clear_error();
}
pub struct CBytesGuard {
inner: RayBytes,
}
impl CBytesGuard {
pub fn from(inner: RayBytes) -> Option<Self> {
if inner.data.is_null() {
None
} else {
Some(Self { inner })
}
}
pub fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.inner.data as *const u8, self.inner.len) }
}
pub fn into_vec(self) -> Vec<u8> {
let v = self.as_slice().to_vec();
v
}
}
impl Drop for CBytesGuard {
fn drop(&mut self) {
unsafe { ray_free_bytes(&mut self.inner) }
}
}
pub fn to_cstring(s: &str) -> CString {
CString::new(s).unwrap_or_else(|_| CString::new("").unwrap())
}
pub fn last_error() -> Option<String> {
unsafe {
let ptr = ray_last_error();
if ptr.is_null() {
None
} else {
std::ffi::CStr::from_ptr(ptr)
.to_str()
.ok()
.map(|s| s.to_string())
}
}
}
pub fn clear_error() {
unsafe { ray_clear_error() }
}
pub fn build_args_array(args: &[&[u8]]) -> Vec<RayBytes> {
args.iter()
.map(|b| RayBytes {
data: b.as_ptr() as *const c_char,
len: b.len(),
})
.collect()
}