use crate::{ffi, CorrelationId, Element, Name};
use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use std::rc::Rc;
#[repr(transparent)]
pub struct Message<'a> {
ptr: *mut ffi::blpapi_Message_t,
_life: PhantomData<&'a ()>,
_marker: PhantomData<Rc<()>>, }
impl<'a> Message<'a> {
#[inline]
pub(crate) unsafe fn from_raw(ptr: *mut ffi::blpapi_Message_t) -> Self {
Self {
ptr,
_life: PhantomData,
_marker: PhantomData,
}
}
#[inline(always)]
pub fn elements(&self) -> Element<'a> {
let ptr = unsafe { ffi::blpapi_Message_elements(self.ptr) };
Element::new(ptr)
}
#[inline(always)]
pub fn message_type(&self) -> Name {
self.name()
}
#[inline(always)]
pub fn name(&self) -> Name {
let ptr = unsafe { ffi::blpapi_Message_messageType(self.ptr) };
unsafe { Name::from_raw(NonNull::new(ffi::blpapi_Name_duplicate(ptr)).unwrap()) }
}
#[inline]
pub fn time_received_us(&self) -> Option<i64> {
let mut tp = MaybeUninit::<ffi::blpapi_TimePoint_t>::uninit();
let rc = unsafe { ffi::blpapi_Message_timeReceived(self.ptr as *const _, tp.as_mut_ptr()) };
if rc != 0 {
return None;
}
let tp = unsafe { tp.assume_init() };
let mut dt = MaybeUninit::<ffi::blpapi_HighPrecisionDatetime_t>::uninit();
let rc =
unsafe { ffi::blpapi_HighPrecisionDatetime_fromTimePoint(dt.as_mut_ptr(), &tp, 0) };
if rc != 0 {
return None;
}
let hpdt = crate::HighPrecisionDatetime(unsafe { dt.assume_init() });
Some(hpdt.to_micros())
}
#[inline(always)]
#[allow(dead_code)] pub(crate) fn as_ptr(&self) -> *mut ffi::blpapi_Message_t {
self.ptr
}
#[inline(always)]
pub fn num_correlation_ids(&self) -> usize {
let count = unsafe { ffi::blpapi_Message_numCorrelationIds(self.ptr) };
count.max(0) as usize
}
#[inline]
pub fn correlation_id(&self, index: usize) -> Option<CorrelationId> {
if index >= self.num_correlation_ids() {
return None;
}
unsafe {
let cid = ffi::blpapi_Message_correlationId(self.ptr, index);
Some(CorrelationId::from_ffi(&cid))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_message_size() {
assert_eq!(
std::mem::size_of::<Message>(),
std::mem::size_of::<*mut ()>()
);
}
#[test]
fn test_message_alignment() {
assert_eq!(
std::mem::align_of::<Message>(),
std::mem::align_of::<*mut ()>()
);
}
}