use std::ffi::CStr;
use std::marker::PhantomData;
use std::ptr::NonNull;
use std::rc::Rc;
use crate::ffi;
use crate::name::Name;
use super::type_def::SchemaTypeDefinition;
use super::SchemaStatus;
#[derive(Clone, Copy)]
pub struct SchemaElementDefinition<'owner> {
ptr: *mut ffi::blpapi_SchemaElementDefinition_t,
_owner: PhantomData<&'owner ()>,
_not_send_sync: PhantomData<Rc<()>>,
}
impl<'owner> SchemaElementDefinition<'owner> {
pub(crate) unsafe fn from_raw_unchecked(
ptr: *mut ffi::blpapi_SchemaElementDefinition_t,
) -> Self {
debug_assert!(!ptr.is_null());
Self {
ptr,
_owner: PhantomData,
_not_send_sync: PhantomData,
}
}
pub(crate) fn from_raw(ptr: *mut ffi::blpapi_SchemaElementDefinition_t) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self {
ptr,
_owner: PhantomData,
_not_send_sync: PhantomData,
})
}
}
pub fn name(&self) -> Option<Name> {
unsafe {
let name_ptr = ffi::blpapi_SchemaElementDefinition_name(self.ptr);
NonNull::new(name_ptr).map(|ptr| Name::from_raw(ptr))
}
}
pub fn name_str(&self) -> &str {
unsafe {
let name_ptr = ffi::blpapi_SchemaElementDefinition_name(self.ptr);
if name_ptr.is_null() {
return "";
}
let str_ptr = ffi::blpapi_Name_string(name_ptr);
if str_ptr.is_null() {
return "";
}
CStr::from_ptr(str_ptr).to_str().unwrap_or("")
}
}
pub fn description(&self) -> &str {
unsafe {
let desc_ptr = ffi::blpapi_SchemaElementDefinition_description(self.ptr);
if desc_ptr.is_null() {
return "";
}
CStr::from_ptr(desc_ptr).to_str().unwrap_or("")
}
}
pub fn type_definition(&self) -> SchemaTypeDefinition<'owner> {
unsafe {
let type_ptr = ffi::blpapi_SchemaElementDefinition_type(self.ptr);
SchemaTypeDefinition::from_raw_unchecked(type_ptr)
}
}
pub fn min_values(&self) -> usize {
unsafe { ffi::blpapi_SchemaElementDefinition_minValues(self.ptr) }
}
pub fn max_values(&self) -> usize {
unsafe { ffi::blpapi_SchemaElementDefinition_maxValues(self.ptr) }
}
pub fn is_optional(&self) -> bool {
self.min_values() == 0
}
pub fn is_required(&self) -> bool {
self.min_values() >= 1
}
pub fn is_array(&self) -> bool {
self.max_values() > 1
}
pub fn is_single_value(&self) -> bool {
self.min_values() == 1 && self.max_values() == 1
}
#[cfg(feature = "live")]
pub fn status(&self) -> SchemaStatus {
unsafe {
let status = ffi::blpapi_SchemaElementDefinition_status(self.ptr);
SchemaStatus::from_raw(status)
}
}
#[cfg(not(feature = "live"))]
pub fn status(&self) -> SchemaStatus {
SchemaStatus::Active
}
}
impl std::fmt::Debug for SchemaElementDefinition<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SchemaElementDefinition")
.field("name", &self.name_str())
.field("min_values", &self.min_values())
.field("max_values", &self.max_values())
.finish()
}
}