use ffi::solClient_getLastErrorInfo;
use num_traits::FromPrimitive;
use crate::message::InboundMessage;
use crate::session::SessionEvent;
use crate::SolClientSubCode;
use solace_rs_sys as ffi;
use std::mem;
pub(crate) fn on_message_trampoline<'s, F>(
_closure: &'s F,
) -> ffi::solClient_session_rxMsgCallbackFunc_t
where
F: FnMut(InboundMessage) + Send + 's,
{
Some(static_on_message::<F>)
}
pub(crate) fn on_event_trampoline<'s, F>(
_closure: &'s F,
) -> ffi::solClient_session_eventCallbackFunc_t
where
F: FnMut(SessionEvent) + Send + 's,
{
Some(static_on_event::<F>)
}
pub(crate) extern "C" fn static_no_op_on_message(
_opaque_session_p: ffi::solClient_opaqueSession_pt,
_msg_p: ffi::solClient_opaqueMsg_pt,
_raw_user_closure: *mut ::std::os::raw::c_void,
) -> ffi::solClient_rxMsgCallback_returnCode_t {
ffi::solClient_rxMsgCallback_returnCode_SOLCLIENT_CALLBACK_OK
}
extern "C" fn static_on_message<'s, F>(
_opaque_session_p: ffi::solClient_opaqueSession_pt, msg_p: ffi::solClient_opaqueMsg_pt, raw_user_closure: *mut ::std::os::raw::c_void, ) -> ffi::solClient_rxMsgCallback_returnCode_t
where
F: FnMut(InboundMessage) + Send + 's,
{
let non_null_raw_user_closure = std::ptr::NonNull::new(raw_user_closure);
let Some(raw_user_closure) = non_null_raw_user_closure else {
return ffi::solClient_rxMsgCallback_returnCode_SOLCLIENT_CALLBACK_OK;
};
let message = InboundMessage::from(msg_p);
let user_closure: &mut Box<F> = unsafe { mem::transmute(raw_user_closure) };
user_closure(message);
ffi::solClient_rxMsgCallback_returnCode_SOLCLIENT_CALLBACK_TAKE_MSG
}
pub(crate) extern "C" fn static_no_op_on_event(
_opaque_session_p: ffi::solClient_opaqueSession_pt, _event_info_p: ffi::solClient_session_eventCallbackInfo_pt, _raw_user_closure: *mut ::std::os::raw::c_void, ) {
}
extern "C" fn static_on_event<'s, F>(
_opaque_session_p: ffi::solClient_opaqueSession_pt, event_info_p: ffi::solClient_session_eventCallbackInfo_pt, raw_user_closure: *mut ::std::os::raw::c_void, ) where
F: FnMut(SessionEvent) + Send + 's,
{
let non_null_raw_user_closure = std::ptr::NonNull::new(raw_user_closure);
let Some(raw_user_closure) = non_null_raw_user_closure else {
return;
};
let raw_event = unsafe { (*event_info_p).sessionEvent };
let Some(event) = SessionEvent::from_u32(raw_event) else {
return;
};
let user_closure: &mut Box<F> = unsafe { mem::transmute(raw_user_closure) };
user_closure(event);
}
pub(crate) fn get_last_error_info() -> SolClientSubCode {
unsafe {
let erno = solClient_getLastErrorInfo();
let subcode = (*erno).subCode;
let repr_raw: [u8; 256] = mem::transmute((*erno).errorStr);
let repr = std::ffi::CStr::from_bytes_until_nul(&repr_raw).unwrap();
SolClientSubCode {
subcode,
error_string: repr.to_string_lossy().to_string(),
}
}
}