use std::ffi::c_char;
use blazen_core::distributed::{
RunEvent as InnerRunEvent, RunStateSnapshot as InnerRunStateSnapshot,
RunStatus as InnerRunStatus, WorkerInfo as InnerWorkerInfo,
};
use crate::string::alloc_cstring;
pub const BLAZEN_RUN_STATUS_PENDING: u32 = 0;
pub const BLAZEN_RUN_STATUS_RUNNING: u32 = 1;
pub const BLAZEN_RUN_STATUS_COMPLETED: u32 = 2;
pub const BLAZEN_RUN_STATUS_FAILED: u32 = 3;
pub const BLAZEN_RUN_STATUS_CANCELLED: u32 = 4;
fn status_to_u32(status: InnerRunStatus) -> u32 {
match status {
InnerRunStatus::Pending => BLAZEN_RUN_STATUS_PENDING,
InnerRunStatus::Running => BLAZEN_RUN_STATUS_RUNNING,
InnerRunStatus::Completed => BLAZEN_RUN_STATUS_COMPLETED,
InnerRunStatus::Failed => BLAZEN_RUN_STATUS_FAILED,
InnerRunStatus::Cancelled => BLAZEN_RUN_STATUS_CANCELLED,
}
}
pub struct BlazenRunStateSnapshot(pub(crate) InnerRunStateSnapshot);
impl BlazenRunStateSnapshot {
pub(crate) fn into_ptr(self) -> *mut BlazenRunStateSnapshot {
Box::into_raw(Box::new(self))
}
}
impl From<InnerRunStateSnapshot> for BlazenRunStateSnapshot {
fn from(inner: InnerRunStateSnapshot) -> Self {
Self(inner)
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_run_id(
snap: *const BlazenRunStateSnapshot,
) -> *mut c_char {
if snap.is_null() {
return std::ptr::null_mut();
}
let snap = unsafe { &*snap };
alloc_cstring(&snap.0.run_id.to_string())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_status(
snap: *const BlazenRunStateSnapshot,
) -> u32 {
if snap.is_null() {
return BLAZEN_RUN_STATUS_PENDING;
}
let snap = unsafe { &*snap };
status_to_u32(snap.0.status)
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_started_at_ms(
snap: *const BlazenRunStateSnapshot,
) -> u64 {
if snap.is_null() {
return 0;
}
let snap = unsafe { &*snap };
snap.0.started_at_ms
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_completed_at_ms(
snap: *const BlazenRunStateSnapshot,
out_ms: *mut u64,
has_value: *mut i32,
) -> i32 {
if snap.is_null() {
return -1;
}
let snap = unsafe { &*snap };
let (value, present) = match snap.0.completed_at_ms {
Some(v) => (v, 1),
None => (0, 0),
};
if !out_ms.is_null() {
unsafe {
*out_ms = value;
}
}
if !has_value.is_null() {
unsafe {
*has_value = present;
}
}
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_assigned_to(
snap: *const BlazenRunStateSnapshot,
) -> *mut c_char {
if snap.is_null() {
return std::ptr::null_mut();
}
let snap = unsafe { &*snap };
match &snap.0.assigned_to {
Some(s) => alloc_cstring(s),
None => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_last_event_at_ms(
snap: *const BlazenRunStateSnapshot,
out_ms: *mut u64,
has_value: *mut i32,
) -> i32 {
if snap.is_null() {
return -1;
}
let snap = unsafe { &*snap };
let (value, present) = match snap.0.last_event_at_ms {
Some(v) => (v, 1),
None => (0, 0),
};
if !out_ms.is_null() {
unsafe {
*out_ms = value;
}
}
if !has_value.is_null() {
unsafe {
*has_value = present;
}
}
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_output_json(
snap: *const BlazenRunStateSnapshot,
) -> *mut c_char {
if snap.is_null() {
return std::ptr::null_mut();
}
let snap = unsafe { &*snap };
match snap.0.output.as_ref() {
Some(v) => match serde_json::to_string(v) {
Ok(s) => alloc_cstring(&s),
Err(_) => std::ptr::null_mut(),
},
None => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_error(
snap: *const BlazenRunStateSnapshot,
) -> *mut c_char {
if snap.is_null() {
return std::ptr::null_mut();
}
let snap = unsafe { &*snap };
match &snap.0.error {
Some(s) => alloc_cstring(s),
None => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_state_snapshot_free(snap: *mut BlazenRunStateSnapshot) {
if snap.is_null() {
return;
}
drop(unsafe { Box::from_raw(snap) });
}
pub struct BlazenWorkerInfo(pub(crate) InnerWorkerInfo);
impl BlazenWorkerInfo {
pub(crate) fn into_ptr(self) -> *mut BlazenWorkerInfo {
Box::into_raw(Box::new(self))
}
}
impl From<InnerWorkerInfo> for BlazenWorkerInfo {
fn from(inner: InnerWorkerInfo) -> Self {
Self(inner)
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_node_id(info: *const BlazenWorkerInfo) -> *mut c_char {
if info.is_null() {
return std::ptr::null_mut();
}
let info = unsafe { &*info };
alloc_cstring(&info.0.node_id)
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_capabilities_json(
info: *const BlazenWorkerInfo,
) -> *mut c_char {
if info.is_null() {
return std::ptr::null_mut();
}
let info = unsafe { &*info };
let json: Vec<serde_json::Value> = info
.0
.capabilities
.iter()
.map(|c| {
serde_json::json!({
"kind": c.kind,
"version": c.version,
})
})
.collect();
match serde_json::to_string(&json) {
Ok(s) => alloc_cstring(&s),
Err(_) => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_tags_json(
info: *const BlazenWorkerInfo,
) -> *mut c_char {
if info.is_null() {
return std::ptr::null_mut();
}
let info = unsafe { &*info };
match serde_json::to_string(&info.0.tags) {
Ok(s) => alloc_cstring(&s),
Err(_) => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_admission_json(
info: *const BlazenWorkerInfo,
) -> *mut c_char {
if info.is_null() {
return std::ptr::null_mut();
}
let info = unsafe { &*info };
let value = match &info.0.admission {
blazen_core::distributed::AdmissionMode::Fixed { max_in_flight } => {
serde_json::json!({ "mode": "Fixed", "max_in_flight": max_in_flight })
}
blazen_core::distributed::AdmissionMode::VramBudget { max_vram_mb } => {
serde_json::json!({ "mode": "VramBudget", "max_vram_mb": max_vram_mb })
}
blazen_core::distributed::AdmissionMode::Reactive => {
serde_json::json!({ "mode": "Reactive" })
}
};
match serde_json::to_string(&value) {
Ok(s) => alloc_cstring(&s),
Err(_) => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_in_flight(info: *const BlazenWorkerInfo) -> u32 {
if info.is_null() {
return 0;
}
let info = unsafe { &*info };
info.0.in_flight
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_connected_at_ms(info: *const BlazenWorkerInfo) -> u64 {
if info.is_null() {
return 0;
}
let info = unsafe { &*info };
info.0.connected_at_ms
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_free(info: *mut BlazenWorkerInfo) {
if info.is_null() {
return;
}
drop(unsafe { Box::from_raw(info) });
}
pub struct BlazenWorkerInfoList(pub(crate) Vec<InnerWorkerInfo>);
impl BlazenWorkerInfoList {
pub(crate) fn into_ptr(self) -> *mut BlazenWorkerInfoList {
Box::into_raw(Box::new(self))
}
}
impl From<Vec<InnerWorkerInfo>> for BlazenWorkerInfoList {
fn from(workers: Vec<InnerWorkerInfo>) -> Self {
Self(workers)
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_list_count(list: *const BlazenWorkerInfoList) -> usize {
if list.is_null() {
return 0;
}
let list = unsafe { &*list };
list.0.len()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_list_get(
list: *const BlazenWorkerInfoList,
index: usize,
) -> *mut BlazenWorkerInfo {
if list.is_null() {
return std::ptr::null_mut();
}
let list = unsafe { &*list };
match list.0.get(index) {
Some(info) => BlazenWorkerInfo(info.clone()).into_ptr(),
None => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_worker_info_list_free(list: *mut BlazenWorkerInfoList) {
if list.is_null() {
return;
}
drop(unsafe { Box::from_raw(list) });
}
pub struct BlazenRunEvent(pub(crate) InnerRunEvent);
impl From<InnerRunEvent> for BlazenRunEvent {
fn from(inner: InnerRunEvent) -> Self {
Self(inner)
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_event_run_id(event: *const BlazenRunEvent) -> *mut c_char {
if event.is_null() {
return std::ptr::null_mut();
}
let event = unsafe { &*event };
alloc_cstring(&event.0.run_id.to_string())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_event_event_type(event: *const BlazenRunEvent) -> *mut c_char {
if event.is_null() {
return std::ptr::null_mut();
}
let event = unsafe { &*event };
alloc_cstring(&event.0.event_type)
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_event_data_json(event: *const BlazenRunEvent) -> *mut c_char {
if event.is_null() {
return std::ptr::null_mut();
}
let event = unsafe { &*event };
match serde_json::to_string(&event.0.data) {
Ok(s) => alloc_cstring(&s),
Err(_) => std::ptr::null_mut(),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_event_timestamp_ms(event: *const BlazenRunEvent) -> u64 {
if event.is_null() {
return 0;
}
let event = unsafe { &*event };
event.0.timestamp_ms
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn blazen_run_event_free(event: *mut BlazenRunEvent) {
if event.is_null() {
return;
}
drop(unsafe { Box::from_raw(event) });
}