use crate::{bindings::*, *};
use std::ptr;
pub struct Arguments<'args> {
ci: pbcallinfo,
count: pbint,
session: Session,
_marker: PhantomData<&'args pbcallinfo>
}
impl<'args> Arguments<'args> {
pub(crate) unsafe fn from_ptr(ci: pbcallinfo, session: Session) -> Arguments<'args> {
let count = ffi::pbargs_GetCount(ci.as_ref().pArgs);
Arguments {
ci,
count,
session,
_marker: PhantomData
}
}
pub fn as_ref(&self) -> ArgumentsRef {
unsafe { ArgumentsRef::from_ptr(self.ci.as_ref().pArgs, self.session.clone()) }
}
pub fn count(&self) -> pbint { self.count }
pub fn get(&self, index: pbint) -> Value<'args> {
if let Ok(val) = self.try_get(index) {
val
} else {
panic!("arg index {} is out of bound {}", index, self.count)
}
}
pub fn try_get(&self, index: pbint) -> Result<Value<'args>> {
if index < 0 || index >= self.count {
return Err(PBXRESULT::E_ARRAY_INDEX_OUTOF_BOUNDS);
}
unsafe { Ok(Value::from_ptr(ffi::pbargs_GetAt(self.ci.as_ref().pArgs, index), self.session.clone())) }
}
pub fn add_int(&mut self, value: impl Into<Option<pbint>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddIntArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_uint(&mut self, value: impl Into<Option<pbuint>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddUintArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_long(&mut self, value: impl Into<Option<pblong>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddLongArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_ulong(&mut self, value: impl Into<Option<pbulong>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddUlongArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_longlong(&mut self, value: impl Into<Option<pblonglong>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddLongLongArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_real(&mut self, value: impl Into<Option<pbreal>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddRealArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_double(&mut self, value: impl Into<Option<pbdouble>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddDoubleArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
#[cfg(feature = "decimal")]
pub fn add_dec(&mut self, value: impl Into<Option<Decimal>>) -> Result<()> {
unsafe {
let value = value.into().map(|v| self.session.new_pbdec(v));
let pbxr = ffi::pbsession_AddDecArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_string<T, D>(&mut self, value: T) -> Result<()>
where
T: Into<Option<D>>,
D: AsPBStr
{
let value = value.into();
unsafe {
let value = value.map(|v| v.as_pbstr().as_ptr());
let pbxr = ffi::pbsession_AddStringArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(ptr::null()),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_bool(&mut self, value: impl Into<Option<bool>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddBoolArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default().into(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_blob<'a>(&mut self, value: impl Into<Option<&'a [u8]>>) -> Result<()> {
let value = value.into();
if let Some(ref value) = value {
if value.is_empty() {
return Err(PBXRESULT::E_OUTOF_MEMORY);
}
}
unsafe {
let value = value.map(|v| self.session.new_pbblob(v));
let pbxr = ffi::pbsession_AddBlobArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
#[cfg(feature = "datetime")]
pub fn add_date(&mut self, value: impl Into<Option<NaiveDate>>) -> Result<()> {
unsafe {
let value = value.into().map(|v| self.session.new_pbdate(v));
let pbxr = ffi::pbsession_AddDateArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
#[cfg(feature = "datetime")]
pub fn add_time(&mut self, value: impl Into<Option<NaiveTime>>) -> Result<()> {
unsafe {
let value = value.into().map(|v| self.session.new_pbtime(v));
let pbxr = ffi::pbsession_AddTimeArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
#[cfg(feature = "datetime")]
pub fn add_datetime(&mut self, value: impl Into<Option<NaiveDateTime>>) -> Result<()> {
unsafe {
let value = value.into().map(|v| self.session.new_pbdatetime(v));
let pbxr = ffi::pbsession_AddDateTimeArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_char(&mut self, value: impl Into<Option<PBChar>>) -> Result<()> {
let value = value.into();
unsafe {
let pbxr = ffi::pbsession_AddCharArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or_default(),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_object<'a, 'b: 'a>(&mut self, value: impl Into<Option<&'a Object<'b>>>) -> Result<()> {
unsafe {
let value = value.into().map(|v| v.as_ptr());
let pbxr = ffi::pbsession_AddObjectArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
pub fn add_array<'a, 'b: 'a>(&mut self, value: impl Into<Option<&'a Array<'b>>>) -> Result<()> {
unsafe {
let value = value.into().map(|v| v.as_ptr());
let pbxr = ffi::pbsession_AddArrayArgument(
self.session.as_ptr(),
self.ci,
value.unwrap_or(NonNull::new_unchecked(0 as _)),
value.is_none().into()
);
if pbxr.is_ok() {
self.count += 1;
}
pbxr.into()
}
}
}
pub struct ArgumentsRef<'args> {
ptr: pbarguments,
count: pbint,
session: Session,
_marker: PhantomData<&'args pbarguments>
}
impl<'args> ArgumentsRef<'args> {
pub(crate) unsafe fn from_ptr(ptr: pbarguments, session: Session) -> ArgumentsRef<'args> {
let count = ffi::pbargs_GetCount(ptr);
ArgumentsRef {
ptr,
count,
session,
_marker: PhantomData
}
}
pub(crate) fn clone(&self) -> ArgumentsRef<'args> {
ArgumentsRef {
ptr: self.ptr,
count: self.count,
session: unsafe { self.session.clone() },
_marker: PhantomData
}
}
pub fn count(&self) -> pbint { self.count }
pub fn get(&self, index: pbint) -> Value<'args> {
if let Ok(val) = self.try_get(index) {
val
} else {
panic!("arg index {} is out of bound {}", index, self.count)
}
}
pub fn try_get(&self, index: pbint) -> Result<Value<'args>> {
if index < 0 || index >= self.count {
return Err(PBXRESULT::E_ARRAY_INDEX_OUTOF_BOUNDS);
}
unsafe { Ok(Value::from_ptr(ffi::pbargs_GetAt(self.ptr, index), self.session.clone())) }
}
}