1use crate::{bindings::*, invoker::GlobalFunction, value::FromValueOwned, *};
2use std::{borrow::Cow, ops::Deref};
3
4#[repr(transparent)]
6pub struct Session {
7 ptr: pbsession
8}
9
10impl Session {
11 pub(crate) unsafe fn from_ptr(ptr: pbsession) -> Session {
12 Session {
13 ptr
14 }
15 }
16 pub(crate) fn as_ptr(&self) -> pbsession { self.ptr }
17
18 pub unsafe fn clone(&self) -> Session {
24 Session {
25 ptr: self.ptr
26 }
27 }
28
29 pub fn restart_requested(&self) -> bool { unsafe { ffi::pbsession_RestartRequested(self.ptr).into() } }
31
32 pub fn has_visual_object(&self) -> bool { unsafe { ffi::pbsession_HasPBVisualObject(self.ptr).into() } }
34
35 pub fn process_message(&self) -> bool { unsafe { ffi::pbsession_ProcessPBMessage(self.ptr).into() } }
41
42 pub(crate) fn get_system_group(&self) -> pbgroup { unsafe { ffi::pbsession_GetSystemGroup(self.ptr) } }
44
45 pub(crate) fn find_group(&self, name: impl AsPBStr, r#type: GroupType) -> Option<pbgroup> {
47 unsafe { ffi::pbsession_FindGroup(self.ptr, name.as_pbstr().as_ptr(), r#type) }
48 }
49
50 pub(crate) fn find_class(&self, group: pbgroup, name: impl AsPBStr) -> Option<pbclass> {
52 unsafe { ffi::pbsession_FindClass(self.ptr, group, name.as_pbstr().as_ptr()) }
53 }
54
55 pub(crate) fn get_group(&self, mut cls: pbclass) -> Option<pbgroup> {
59 unsafe {
60 'outer: loop {
61 let cls_name = ffi::pbsession_GetClassName(self.ptr, cls);
62 for group_type in (GroupType::Application as i32)..(GroupType::Unknown as i32) {
63 let group = ffi::pbsession_FindGroup(self.ptr, cls_name, group_type.into());
64 if group.is_some() {
65 break 'outer group;
66 }
67 }
68 match ffi::pbsession_GetSuperClass(self.ptr, cls) {
69 Some(v) => cls = v,
70 None => break None
71 }
72 }
73 }
74 }
75
76 pub fn has_exception(&self) -> bool { unsafe { ffi::pbsession_HasExceptionThrown(self.ptr).into() } }
82
83 pub fn clear_exception(&self) {
85 unsafe {
86 ffi::pbsession_ClearException(self.ptr);
87 }
88 }
89
90 pub fn throw_exception(&self, exstr: impl AsPBStr) -> Result<()> {
100 let mut ex = self.new_system_object(pbstr!("PBXRuntimeError"))?;
101 unsafe { ex.set_var_str_unchecked(pbstr!("text"), exstr)? };
102 unsafe {
103 ffi::pbsession_ThrowException(self.ptr, ex.as_ptr());
104 }
105 Ok(())
106 }
107
108 pub fn set_prop<T, D>(&self, name: T, data: &'static D)
114 where
115 T: AsPBStr,
116 D: Sized
117 {
118 self.set_prop_ptr(name, data as *const D)
119 }
120
121 pub fn set_prop_ptr<T, D>(&self, name: T, data: *const D)
123 where
124 T: AsPBStr,
125 D: Sized
126 {
127 unsafe { ffi::pbsession_SetProp(self.ptr, name.as_pbstr().as_ptr(), data as _) }
128 }
129
130 pub fn get_prop_ptr<T, D>(&self, name: T) -> *const D
132 where
133 T: AsPBStr,
134 D: Sized
135 {
136 unsafe { ffi::pbsession_GetProp(self.ptr, name.as_pbstr().as_ptr()) as *const D }
137 }
138 pub unsafe fn get_prop_ref<'a, T, D>(&self, name: T) -> Option<&'a D>
145 where
146 T: AsPBStr,
147 D: Sized
148 {
149 let ptr: *const D = self.get_prop_ptr(name);
150 if ptr.is_null() {
151 None
152 } else {
153 Some(&*ptr)
154 }
155 }
156
157 pub unsafe fn get_prop_mut<'a, T, D>(&self, name: T) -> Option<&'a mut D>
164 where
165 T: AsPBStr,
166 D: Sized
167 {
168 let ptr: *const D = self.get_prop_ptr(name);
169 if ptr.is_null() {
170 None
171 } else {
172 Some(&mut *(ptr as *mut D))
173 }
174 }
175
176 pub fn remove_prop(&self, name: impl AsPBStr) {
182 unsafe { ffi::pbsession_RemoveProp(self.ptr, name.as_pbstr().as_ptr()) }
183 }
184
185 pub fn get_enum_item_value(&self, enum_name: impl AsPBStr, item_name: impl AsPBStr) -> pblong {
198 unsafe {
199 ffi::pbsession_GetEnumItemValue(
200 self.ptr,
201 enum_name.as_pbstr().as_ptr(),
202 item_name.as_pbstr().as_ptr()
203 )
204 }
205 }
206
207 pub fn get_enum_item_name<'a>(
216 &'a self,
217 enum_name: impl AsPBStr,
218 item_value: pblong
219 ) -> Option<&'a PBStr> {
220 unsafe {
221 let cstr = ffi::pbsession_GetEnumItemName(self.ptr, enum_name.as_pbstr().as_ptr(), item_value);
222 if cstr.is_null() {
223 None
224 } else {
225 Some(PBStr::from_ptr_str(cstr))
226 }
227 }
228 }
229
230 #[inline]
235 pub(crate) unsafe fn get_string_unchecked<'a>(&self, pbstr: pbstring) -> Option<&'a PBStr> {
236 let cstr = ffi::pbsession_GetString(self.ptr, pbstr);
237 if !cstr.is_null() {
238 Some(PBStr::from_ptr_str(cstr))
239 } else {
240 None
241 }
242 }
243
244 pub fn new_user_object<'a>(&'a self, cls_name: impl AsPBStr) -> Result<Object<'a>> {
256 unsafe {
257 let cls_name = cls_name.as_pbstr();
258 let group = self
259 .find_group(cls_name.as_ref(), GroupType::UserObject)
260 .ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
261 let cls = self.find_class(group, cls_name).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
262 let ptr = ffi::pbsession_NewObject(self.ptr, cls);
263 Ok(Object::from_ptr(ptr, self.clone()))
264 }
265 }
266
267 pub fn new_system_object<'a>(&'a self, cls_name: impl AsPBStr) -> Result<Object<'a>> {
275 unsafe {
276 let group = self.get_system_group();
277 let cls = self.find_class(group, cls_name).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
278 let ptr = ffi::pbsession_NewObject(self.ptr, cls);
279 Ok(Object::from_ptr(ptr, self.clone()))
280 }
281 }
282
283 pub fn new_object<'a>(&'a self, cls_name: impl AsPBStr) -> Result<Object<'a>> {
292 let cls_name = cls_name.as_pbstr();
293 self.new_user_object(cls_name.as_ref()).or_else(|_| self.new_system_object(cls_name))
294 }
295
296 pub fn new_array<'a>(&'a self, item_type: ValueType) -> Result<Array<'a>> {
315 unsafe {
316 let ptr = ffi::pbsession_NewUnboundedSimpleArray(self.ptr, item_type)
317 .ok_or(PBXRESULT::E_INVALID_ARGUMENT)?;
318 Ok(Array::from_ptr(ptr, false, self.clone()))
319 }
320 }
321
322 pub fn new_bounded_array<'a>(
348 &'a self,
349 item_type: ValueType,
350 dims: &[(pblong, pblong)]
351 ) -> Result<Array<'a>> {
352 unsafe {
353 let dims: Vec<ArrayBound> = dims
354 .iter()
355 .map(|&(lowerBound, upperBound)| {
356 ArrayBound {
357 lowerBound,
358 upperBound
359 }
360 })
361 .collect();
362 let ptr =
363 ffi::pbsession_NewBoundedSimpleArray(self.ptr, item_type, dims.len() as u16, dims.as_ptr())
364 .ok_or(PBXRESULT::E_INVALID_ARGUMENT)?;
365 Ok(Array::from_ptr(ptr, false, self.clone()))
366 }
367 }
368
369 pub fn new_user_object_array<'a>(&'a self, cls_name: impl AsPBStr) -> Result<Array<'a>> {
385 let cls_name = cls_name.as_pbstr();
386 let group =
387 self.find_group(cls_name.as_ref(), GroupType::UserObject).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
388 let cls = self.find_class(group, cls_name).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
389 self.new_object_array_impl(cls)
390 }
391
392 pub fn new_system_object_array<'a>(&'a self, cls_name: impl AsPBStr) -> Result<Array<'a>> {
408 let group = self.get_system_group();
409 let cls = self.find_class(group, cls_name).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
410 self.new_object_array_impl(cls)
411 }
412
413 pub fn new_object_array<'a>(&'a self, cls_name: impl AsPBStr) -> Result<Array<'a>> {
429 let cls_name = cls_name.as_pbstr();
430 self.new_user_object_array(cls_name.as_ref()).or_else(|_| self.new_system_object_array(cls_name))
431 }
432
433 fn new_object_array_impl<'a>(&'a self, cls: pbclass) -> Result<Array<'a>> {
434 unsafe {
435 let ptr =
436 ffi::pbsession_NewUnboundedObjectArray(self.ptr, cls).ok_or(PBXRESULT::E_INVALID_ARGUMENT)?;
437 Ok(Array::from_ptr(ptr, true, self.clone()))
438 }
439 }
440
441 pub fn new_bounded_user_object_array<'a>(
469 &'a self,
470 cls_name: impl AsPBStr,
471 dims: &[(pblong, pblong)]
472 ) -> Result<Array<'a>> {
473 let cls_name = cls_name.as_pbstr();
474 let group =
475 self.find_group(cls_name.as_ref(), GroupType::UserObject).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
476 let cls = self.find_class(group, cls_name).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
477 self.new_bounded_object_array_impl(cls, dims)
478 }
479
480 pub fn new_bounded_system_object_array<'a>(
508 &'a self,
509 cls_name: impl AsPBStr,
510 dims: &[(pblong, pblong)]
511 ) -> Result<Array<'a>> {
512 let group = self.get_system_group();
513 let cls = self.find_class(group, cls_name).ok_or(PBXRESULT::E_NO_SUCH_CLASS)?;
514 self.new_bounded_object_array_impl(cls, dims)
515 }
516
517 pub fn new_bounded_object_array<'a>(
545 &'a self,
546 cls_name: impl AsPBStr,
547 dims: &[(pblong, pblong)]
548 ) -> Result<Array<'a>> {
549 let cls_name = cls_name.as_pbstr();
550 self.new_bounded_user_object_array(cls_name.as_ref(), dims)
551 .or_else(|_| self.new_bounded_system_object_array(cls_name, dims))
552 }
553
554 fn new_bounded_object_array_impl<'a>(
555 &'a self,
556 cls: pbclass,
557 dims: &[(pblong, pblong)]
558 ) -> Result<Array<'a>> {
559 unsafe {
560 let dims: Vec<ArrayBound> = dims
561 .iter()
562 .map(|&(lowerBound, upperBound)| {
563 ArrayBound {
564 lowerBound,
565 upperBound
566 }
567 })
568 .collect();
569 let ptr = ffi::pbsession_NewBoundedObjectArray(self.ptr, cls, dims.len() as u16, dims.as_ptr())
570 .ok_or(PBXRESULT::E_INVALID_ARGUMENT)?;
571 Ok(Array::from_ptr(ptr, true, self.clone()))
572 }
573 }
574
575 pub(crate) fn new_pbblob(&self, bin: impl AsRef<[u8]>) -> pbblob {
580 let bin = bin.as_ref();
581 assert!(!bin.is_empty());
582 unsafe { ffi::pbsession_NewBlob(self.ptr, bin.as_ptr() as _, bin.len() as pblong) }
583 }
584 pub(crate) unsafe fn get_blob_unchecked<'a>(&self, pbbin: pbblob) -> &'a [u8] {
585 let ptr = ffi::pbsession_GetBlob(self.ptr, pbbin);
586 let len = if !ptr.is_null() {
587 ffi::pbsession_GetBlobLength(self.ptr, pbbin)
588 } else {
589 0
590 };
591 std::slice::from_raw_parts(ptr as *const u8, len as usize)
592 }
593
594 #[cfg(feature = "datetime")]
599 pub(crate) fn new_pbdate(&self, dt: NaiveDate) -> pbdate {
600 unsafe {
601 let pbdt = ffi::pbsession_NewDate(self.ptr);
602 let pbxr = ffi::pbsession_SetDate(
603 self.ptr,
604 pbdt,
605 dt.year() as pbint,
606 dt.month() as pbint,
607 dt.day() as pbint
608 );
609 assert!(pbxr == PBXRESULT::OK);
610 pbdt
611 }
612 }
613 #[cfg(feature = "datetime")]
614 pub(crate) fn new_pbtime(&self, tm: NaiveTime) -> pbtime {
615 unsafe {
616 let pbtm = ffi::pbsession_NewTime(self.ptr);
617 let pbxr = ffi::pbsession_SetTime(
618 self.ptr,
619 pbtm,
620 tm.hour() as pbint,
621 tm.minute() as pbint,
622 tm.second() as pbdouble + tm.nanosecond() as pbdouble / 1000_000_000.0
623 );
624 assert!(pbxr == PBXRESULT::OK);
625 pbtm
626 }
627 }
628 #[cfg(feature = "datetime")]
629 pub(crate) fn new_pbdatetime(&self, dtt: NaiveDateTime) -> pbdatetime {
630 unsafe {
631 let pbdtt = ffi::pbsession_NewDateTime(self.ptr);
632 let pbxr = ffi::pbsession_SetDateTime(
633 self.ptr,
634 pbdtt,
635 dtt.year() as pbint,
636 dtt.month() as pbint,
637 dtt.day() as pbint,
638 dtt.hour() as pbint,
639 dtt.minute() as pbint,
640 dtt.second() as pbdouble + dtt.nanosecond() as pbdouble / 1000_000_000.0
641 );
642 assert!(pbxr == PBXRESULT::OK);
643 pbdtt
644 }
645 }
646 #[cfg(feature = "datetime")]
647 pub(crate) unsafe fn get_date_unchecked(&self, pbdt: pbdate) -> NaiveDate {
648 let mut year = 0;
649 let mut month = 0;
650 let mut day = 0;
651 let pbxr = ffi::pbsession_SplitDate(self.ptr, pbdt, &mut year, &mut month, &mut day);
652 assert!(pbxr == PBXRESULT::OK);
653 NaiveDate::from_ymd(year as i32, month as u32, day as u32)
654 }
655 #[cfg(feature = "datetime")]
656 pub(crate) unsafe fn get_time_unchecked(&self, pbtm: pbtime) -> NaiveTime {
657 let mut hour = 0;
658 let mut minute = 0;
659 let mut second = 0.0;
660 let pbxr = ffi::pbsession_SplitTime(self.ptr, pbtm, &mut hour, &mut minute, &mut second);
661 assert!(pbxr == PBXRESULT::OK);
662 NaiveTime::from_hms_nano(
663 hour as u32,
664 minute as u32,
665 second as u32,
666 ((second - second.trunc()) * 1000_000_000.0) as u32
667 )
668 }
669 #[cfg(feature = "datetime")]
670 pub(crate) unsafe fn get_datetime_unchecked(&self, pbdtt: pbdatetime) -> NaiveDateTime {
671 let mut year = 0;
672 let mut month = 0;
673 let mut day = 0;
674 let mut hour = 0;
675 let mut minute = 0;
676 let mut second = 0.0;
677 let pbxr = ffi::pbsession_SplitDateTime(
678 self.ptr,
679 pbdtt,
680 &mut year,
681 &mut month,
682 &mut day,
683 &mut hour,
684 &mut minute,
685 &mut second
686 );
687 assert!(pbxr == PBXRESULT::OK);
688 NaiveDateTime::new(
689 NaiveDate::from_ymd(year as i32, month as u32, day as u32),
690 NaiveTime::from_hms_nano(
691 hour as u32,
692 minute as u32,
693 second as u32,
694 ((second - second.trunc()) * 1000_000_000.0) as u32
695 )
696 )
697 }
698
699 #[cfg(feature = "decimal")]
703 pub(crate) fn new_pbdec(&self, dec: Decimal) -> pbdec {
704 unsafe {
705 let dec = PBString::from_str_unchecked(dec.to_string());
706 let pbdec = ffi::pbsession_NewDecimal(self.ptr);
707 let pbxr = ffi::pbsession_SetDecimal(self.ptr, pbdec, dec.as_ptr());
708 assert!(pbxr == PBXRESULT::OK);
709 pbdec
710 }
711 }
712 #[cfg(feature = "decimal")]
713 pub(crate) unsafe fn get_dec_unchecked(&self, pbdec: pbdec) -> Decimal {
714 let cstr = ffi::pbsession_GetDecimalString(self.ptr, pbdec);
715 let str = String::from_pbstr_unchecked(cstr);
716 ffi::pbsession_ReleaseDecimalString(self.ptr, cstr);
717 str.parse().unwrap()
718 }
719}
720
721pub trait GlobalVarId {
727 fn var_id(&self, session: &Session) -> FieldId;
728}
729
730impl<T: AsPBStr> GlobalVarId for T {
731 #[inline]
732 fn var_id(&self, session: &Session) -> FieldId {
733 let pbstr = self.as_pbstr();
734 session
735 .get_var_id(pbstr.as_ref())
736 .ok_or_else(|| format!("invalid global var {}", pbstr.to_string_lossy()))
737 .unwrap()
738 }
739}
740impl GlobalVarId for FieldId {
741 #[inline]
742 fn var_id(&self, _session: &Session) -> FieldId { *self }
743}
744impl GlobalVarId for Option<FieldId> {
745 #[inline]
746 fn var_id(&self, _session: &Session) -> FieldId { self.unwrap() }
747}
748
749impl Session {
750 pub fn get_var_id(&self, name: impl AsPBStr) -> Option<FieldId> {
759 unsafe {
760 let fid = ffi::pbsession_GetGlobalVarID(self.ptr, name.as_pbstr().as_ptr());
761 if fid.is_undefined() {
762 None
763 } else {
764 Some(fid)
765 }
766 }
767 }
768
769 pub fn has_var(&self, name: impl AsPBStr) -> bool { self.get_var_id(name).is_some() }
779
780 pub fn get_var_type(&self, fid: impl GlobalVarId) -> ValueType {
794 unsafe { ffi::pbsession_GetGlobalVarType(self.ptr, fid.var_id(self)) }
795 }
796
797 pub fn is_var_null(&self, fid: impl GlobalVarId) -> bool {
803 unsafe { ffi::pbsession_IsGlobalVarNull(self.ptr, fid.var_id(self)).into() }
804 }
805
806 pub fn is_var_array(&self, fid: impl GlobalVarId) -> bool {
812 unsafe { ffi::pbsession_IsGlobalVarArray(self.ptr, fid.var_id(self)).into() }
813 }
814
815 pub fn is_var_object(&self, fid: impl GlobalVarId) -> bool {
821 unsafe { ffi::pbsession_IsGlobalVarObject(self.ptr, fid.var_id(self)).into() }
822 }
823
824 pub fn get_var_int(&self, fid: impl GlobalVarId) -> Option<pbint> {
830 let fid = fid.var_id(self);
831 assert!(self.get_var_type(fid) == ValueType::Int);
832 unsafe { self.get_var_int_unchecked(fid) }
833 }
834
835 pub unsafe fn get_var_int_unchecked(&self, fid: impl GlobalVarId) -> Option<pbint> {
845 let mut is_null = Default::default();
846 let v = ffi::pbsession_GetIntGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
847 if is_null == true {
848 None
849 } else {
850 Some(v)
851 }
852 }
853
854 pub fn get_var_uint(&self, fid: impl GlobalVarId) -> Option<pbuint> {
860 let fid = fid.var_id(self);
861 assert!(self.get_var_type(fid) == ValueType::Uint);
862 unsafe { self.get_var_uint_unchecked(fid) }
863 }
864
865 pub unsafe fn get_var_uint_unchecked(&self, fid: impl GlobalVarId) -> Option<pbuint> {
875 let mut is_null = Default::default();
876 let v = ffi::pbsession_GetUintGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
877 if is_null == true {
878 None
879 } else {
880 Some(v)
881 }
882 }
883
884 pub fn get_var_long(&self, fid: impl GlobalVarId) -> Option<pblong> {
890 let fid = fid.var_id(self);
891 assert!(self.get_var_type(fid) == ValueType::Long);
892 unsafe { self.get_var_long_unchecked(fid) }
893 }
894
895 pub unsafe fn get_var_long_unchecked(&self, fid: impl GlobalVarId) -> Option<pblong> {
905 let mut is_null = Default::default();
906 let v = ffi::pbsession_GetLongGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
907 if is_null == true {
908 None
909 } else {
910 Some(v)
911 }
912 }
913
914 pub fn get_var_ulong(&self, fid: impl GlobalVarId) -> Option<pbulong> {
920 let fid = fid.var_id(self);
921 assert!(self.get_var_type(fid) == ValueType::Ulong);
922 unsafe { self.get_var_ulong_unchecked(fid) }
923 }
924
925 pub unsafe fn get_var_ulong_unchecked(&self, fid: impl GlobalVarId) -> Option<pbulong> {
935 let mut is_null = Default::default();
936 let v = ffi::pbsession_GetUlongGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
937 if is_null == true {
938 None
939 } else {
940 Some(v)
941 }
942 }
943
944 pub fn get_var_longlong(&self, fid: impl GlobalVarId) -> Option<pblonglong> {
950 let fid = fid.var_id(self);
951 assert!(self.get_var_type(fid) == ValueType::LongLong);
952 unsafe { self.get_var_longlong_unchecked(fid) }
953 }
954
955 pub unsafe fn get_var_longlong_unchecked(&self, fid: impl GlobalVarId) -> Option<pblonglong> {
965 let mut is_null = Default::default();
966 let v = ffi::pbsession_GetLongLongGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
967 if is_null == true {
968 None
969 } else {
970 Some(v)
971 }
972 }
973
974 pub fn get_var_real(&self, fid: impl GlobalVarId) -> Option<pbreal> {
980 let fid = fid.var_id(self);
981 assert!(self.get_var_type(fid) == ValueType::Real);
982 unsafe { self.get_var_real_unchecked(fid) }
983 }
984
985 pub unsafe fn get_var_real_unchecked(&self, fid: impl GlobalVarId) -> Option<pbreal> {
995 let mut is_null = Default::default();
996 let v = ffi::pbsession_GetRealGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
997 if is_null == true {
998 None
999 } else {
1000 Some(v)
1001 }
1002 }
1003
1004 pub fn get_var_double(&self, fid: impl GlobalVarId) -> Option<pbdouble> {
1010 let fid = fid.var_id(self);
1011 assert!(self.get_var_type(fid) == ValueType::Double);
1012 unsafe { self.get_var_double_unchecked(fid) }
1013 }
1014
1015 pub unsafe fn get_var_double_unchecked(&self, fid: impl GlobalVarId) -> Option<pbdouble> {
1025 let mut is_null = Default::default();
1026 let v = ffi::pbsession_GetDoubleGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1027 if is_null == true {
1028 None
1029 } else {
1030 Some(v)
1031 }
1032 }
1033
1034 #[cfg(feature = "decimal")]
1040 pub fn get_var_dec(&self, fid: impl GlobalVarId) -> Option<Decimal> {
1041 let fid = fid.var_id(self);
1042 assert!(self.get_var_type(fid) == ValueType::Decimal);
1043 unsafe { self.get_var_dec_unchecked(fid) }
1044 }
1045
1046 #[cfg(feature = "decimal")]
1056 pub unsafe fn get_var_dec_unchecked(&self, fid: impl GlobalVarId) -> Option<Decimal> {
1057 let mut is_null = Default::default();
1058 let v = ffi::pbsession_GetDecGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1059 if is_null == true {
1060 None
1061 } else {
1062 Some(self.get_dec_unchecked(v))
1063 }
1064 }
1065
1066 pub unsafe fn get_var_str<'a>(&'a self, fid: impl GlobalVarId) -> Option<&'a PBStr> {
1078 let fid = fid.var_id(self);
1079 assert!(self.get_var_type(fid) == ValueType::String);
1080 self.get_var_str_unchecked(fid)
1081 }
1082
1083 pub unsafe fn get_var_str_unchecked<'a>(&'a self, fid: impl GlobalVarId) -> Option<&'a PBStr> {
1096 let mut is_null = Default::default();
1097 let v = ffi::pbsession_GetStringGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1098 if is_null == true {
1099 None
1100 } else {
1101 self.get_string_unchecked(v)
1102 }
1103 }
1104
1105 pub fn get_var_string(&self, fid: impl GlobalVarId) -> Option<PBString> {
1111 let fid = fid.var_id(self);
1112 assert!(self.get_var_type(fid) == ValueType::String);
1113 unsafe { self.get_var_string_unchecked(fid) }
1114 }
1115
1116 pub unsafe fn get_var_string_unchecked(&self, fid: impl GlobalVarId) -> Option<PBString> {
1126 self.get_var_str_unchecked(fid).map(|v| v.to_ucstring())
1127 }
1128
1129 pub fn get_var_bool(&self, fid: impl GlobalVarId) -> Option<bool> {
1135 let fid = fid.var_id(self);
1136 assert!(self.get_var_type(fid) == ValueType::Boolean);
1137 unsafe { self.get_var_bool_unchecked(fid) }
1138 }
1139
1140 pub unsafe fn get_var_bool_unchecked(&self, fid: impl GlobalVarId) -> Option<bool> {
1150 let mut is_null = Default::default();
1151 let v = ffi::pbsession_GetBoolGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1152 if is_null == true {
1153 None
1154 } else {
1155 Some(v.into())
1156 }
1157 }
1158
1159 pub unsafe fn get_var_blob<'a>(&'a self, fid: impl GlobalVarId) -> Option<&'a [u8]> {
1171 let fid = fid.var_id(self);
1172 assert!(self.get_var_type(fid) == ValueType::Blob);
1173 self.get_var_blob_unchecked(fid)
1174 }
1175
1176 pub unsafe fn get_var_blob_unchecked<'a>(&'a self, fid: impl GlobalVarId) -> Option<&'a [u8]> {
1189 let mut is_null = Default::default();
1190 let v = ffi::pbsession_GetBlobGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1191 if is_null == true {
1192 None
1193 } else {
1194 Some(self.get_blob_unchecked(v))
1195 }
1196 }
1197
1198 #[cfg(feature = "datetime")]
1204 pub fn get_var_date(&self, fid: impl GlobalVarId) -> Option<NaiveDate> {
1205 let fid = fid.var_id(self);
1206 assert!(self.get_var_type(fid) == ValueType::Date);
1207 unsafe { self.get_var_date_unchecked(fid) }
1208 }
1209
1210 #[cfg(feature = "datetime")]
1220 pub unsafe fn get_var_date_unchecked(&self, fid: impl GlobalVarId) -> Option<NaiveDate> {
1221 let mut is_null = Default::default();
1222 let v = ffi::pbsession_GetDateGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1223 if is_null == true {
1224 None
1225 } else {
1226 Some(self.get_date_unchecked(v))
1227 }
1228 }
1229
1230 #[cfg(feature = "datetime")]
1236 pub fn get_var_time(&self, fid: impl GlobalVarId) -> Option<NaiveTime> {
1237 let fid = fid.var_id(self);
1238 assert!(self.get_var_type(fid) == ValueType::Time);
1239 unsafe { self.get_var_time_unchecked(fid) }
1240 }
1241
1242 #[cfg(feature = "datetime")]
1252 pub unsafe fn get_var_time_unchecked(&self, fid: impl GlobalVarId) -> Option<NaiveTime> {
1253 let mut is_null = Default::default();
1254 let v = ffi::pbsession_GetTimeGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1255 if is_null == true {
1256 None
1257 } else {
1258 Some(self.get_time_unchecked(v))
1259 }
1260 }
1261
1262 #[cfg(feature = "datetime")]
1268 pub fn get_var_datetime(&self, fid: impl GlobalVarId) -> Option<NaiveDateTime> {
1269 let fid = fid.var_id(self);
1270 assert!(self.get_var_type(fid) == ValueType::DateTime);
1271 unsafe { self.get_var_datetime_unchecked(fid) }
1272 }
1273
1274 #[cfg(feature = "datetime")]
1284 pub unsafe fn get_var_datetime_unchecked(&self, fid: impl GlobalVarId) -> Option<NaiveDateTime> {
1285 let mut is_null = Default::default();
1286 let v = ffi::pbsession_GetDateTimeGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1287 if is_null == true {
1288 None
1289 } else {
1290 Some(self.get_datetime_unchecked(v))
1291 }
1292 }
1293
1294 pub fn get_var_char(&self, fid: impl GlobalVarId) -> Option<PBChar> {
1300 let fid = fid.var_id(self);
1301 assert!(self.get_var_type(fid) == ValueType::Char);
1302 unsafe { self.get_var_char_unchecked(fid) }
1303 }
1304
1305 pub unsafe fn get_var_char_unchecked(&self, fid: impl GlobalVarId) -> Option<PBChar> {
1315 let mut is_null = Default::default();
1316 let v = ffi::pbsession_GetCharGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1317 if is_null == true {
1318 None
1319 } else {
1320 Some(v)
1321 }
1322 }
1323
1324 pub fn get_var_byte(&self, fid: impl GlobalVarId) -> Option<pbbyte> {
1330 let fid = fid.var_id(self);
1331 assert!(self.get_var_type(fid) == ValueType::Byte);
1332 unsafe { self.get_var_byte_unchecked(fid) }
1333 }
1334
1335 pub unsafe fn get_var_byte_unchecked(&self, fid: impl GlobalVarId) -> Option<pbbyte> {
1345 let mut is_null = Default::default();
1346 let v = ffi::pbsession_GetByteGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1347 if is_null == true {
1348 None
1349 } else {
1350 Some(v)
1351 }
1352 }
1353
1354 pub unsafe fn get_var_object<'a>(&'a self, fid: impl GlobalVarId) -> Option<Object<'a>> {
1366 let fid = fid.var_id(self);
1367 assert!(self.is_var_object(fid));
1368 self.get_var_object_unchecked(fid)
1369 }
1370
1371 pub unsafe fn get_var_object_unchecked<'a>(&'a self, fid: impl GlobalVarId) -> Option<Object<'a>> {
1384 let mut is_null = Default::default();
1385 let v = ffi::pbsession_GetObjectGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1386 if is_null == true {
1387 None
1388 } else {
1389 Some(Object::from_ptr(v, self.clone()))
1390 }
1391 }
1392
1393 pub unsafe fn get_var_array<'a>(&'a self, fid: impl GlobalVarId) -> Option<Array<'a>> {
1405 let fid = fid.var_id(self);
1406 assert!(self.is_var_array(fid));
1407 self.get_var_array_unchecked(fid)
1408 }
1409
1410 pub unsafe fn get_var_array_unchecked<'a>(&'a self, fid: impl GlobalVarId) -> Option<Array<'a>> {
1423 let mut is_null = Default::default();
1424 let v = ffi::pbsession_GetArrayGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1425 if is_null == true {
1426 None
1427 } else {
1428 Some(Array::from_ptr(v, self.is_var_object(fid), self.clone()))
1429 }
1430 }
1431
1432 pub unsafe fn get_var_any<'a>(&'a self, fid: impl GlobalVarId) -> Option<Value<'a>> {
1444 let fid = fid.var_id(self);
1445 assert!(self.get_var_type(fid) == ValueType::Any);
1446 self.get_var_any_unchecked(fid)
1447 }
1448
1449 pub unsafe fn get_var_any_unchecked<'a>(&'a self, fid: impl GlobalVarId) -> Option<Value<'a>> {
1462 let mut is_null = Default::default();
1463 let v = ffi::pbsession_GetPBAnyGlobalVar(self.ptr, fid.var_id(self), &mut is_null);
1464 if is_null == true {
1465 None
1466 } else {
1467 Some(Value::from_ptr(v, self.clone()))
1468 }
1469 }
1470
1471 pub fn set_var_to_null(&self, fid: impl GlobalVarId) {
1477 unsafe { ffi::pbsession_SetGlobalVarToNull(self.ptr, fid.var_id(self)) }
1478 }
1479
1480 pub fn set_var_int(&mut self, fid: impl GlobalVarId, value: pbint) -> Result<()> {
1486 let fid = fid.var_id(self);
1487 assert!(self.get_var_type(fid) == ValueType::Int);
1488 unsafe { ffi::pbsession_SetIntGlobalVar(self.ptr, fid, value).into() }
1489 }
1490
1491 pub unsafe fn set_var_int_unchecked(&mut self, fid: impl GlobalVarId, value: pbint) -> Result<()> {
1501 ffi::pbsession_SetIntGlobalVar(self.ptr, fid.var_id(self), value).into()
1502 }
1503
1504 pub fn set_var_uint(&mut self, fid: impl GlobalVarId, value: pbuint) -> Result<()> {
1510 let fid = fid.var_id(self);
1511 assert!(self.get_var_type(fid) == ValueType::Uint);
1512 unsafe { ffi::pbsession_SetUintGlobalVar(self.ptr, fid, value).into() }
1513 }
1514
1515 pub unsafe fn set_var_uint_unchecked(&mut self, fid: impl GlobalVarId, value: pbuint) -> Result<()> {
1525 ffi::pbsession_SetUintGlobalVar(self.ptr, fid.var_id(self), value).into()
1526 }
1527
1528 pub fn set_var_long(&mut self, fid: impl GlobalVarId, value: pblong) -> Result<()> {
1534 let fid = fid.var_id(self);
1535 assert!(self.get_var_type(fid) == ValueType::Long);
1536 unsafe { ffi::pbsession_SetLongGlobalVar(self.ptr, fid, value).into() }
1537 }
1538
1539 pub unsafe fn set_var_long_unchecked(&mut self, fid: impl GlobalVarId, value: pblong) -> Result<()> {
1549 ffi::pbsession_SetLongGlobalVar(self.ptr, fid.var_id(self), value).into()
1550 }
1551
1552 pub fn set_var_ulong(&mut self, fid: impl GlobalVarId, value: pbulong) -> Result<()> {
1558 let fid = fid.var_id(self);
1559 assert!(self.get_var_type(fid) == ValueType::Ulong);
1560 unsafe { ffi::pbsession_SetUlongGlobalVar(self.ptr, fid, value).into() }
1561 }
1562
1563 pub unsafe fn set_var_ulong_unchecked(&mut self, fid: impl GlobalVarId, value: pbulong) -> Result<()> {
1573 ffi::pbsession_SetUlongGlobalVar(self.ptr, fid.var_id(self), value).into()
1574 }
1575
1576 pub fn set_var_longlong(&mut self, fid: impl GlobalVarId, value: pblonglong) -> Result<()> {
1582 let fid = fid.var_id(self);
1583 assert!(self.get_var_type(fid) == ValueType::LongLong);
1584 unsafe { ffi::pbsession_SetLongLongGlobalVar(self.ptr, fid, value).into() }
1585 }
1586
1587 pub unsafe fn set_var_longlong_unchecked(
1597 &mut self,
1598 fid: impl GlobalVarId,
1599 value: pblonglong
1600 ) -> Result<()> {
1601 ffi::pbsession_SetLongLongGlobalVar(self.ptr, fid.var_id(self), value).into()
1602 }
1603
1604 pub fn set_var_real(&mut self, fid: impl GlobalVarId, value: pbreal) -> Result<()> {
1610 let fid = fid.var_id(self);
1611 assert!(self.get_var_type(fid) == ValueType::Real);
1612 unsafe { ffi::pbsession_SetRealGlobalVar(self.ptr, fid, value).into() }
1613 }
1614
1615 pub unsafe fn set_var_real_unchecked(&mut self, fid: impl GlobalVarId, value: pbreal) -> Result<()> {
1625 ffi::pbsession_SetRealGlobalVar(self.ptr, fid.var_id(self), value).into()
1626 }
1627
1628 pub fn set_var_double(&mut self, fid: impl GlobalVarId, value: pbdouble) -> Result<()> {
1634 let fid = fid.var_id(self);
1635 assert!(self.get_var_type(fid) == ValueType::Double);
1636 unsafe { ffi::pbsession_SetDoubleGlobalVar(self.ptr, fid, value).into() }
1637 }
1638
1639 pub unsafe fn set_var_double_unchecked(&mut self, fid: impl GlobalVarId, value: pbdouble) -> Result<()> {
1649 ffi::pbsession_SetDoubleGlobalVar(self.ptr, fid.var_id(self), value).into()
1650 }
1651
1652 #[cfg(feature = "decimal")]
1658 pub fn set_var_dec(&mut self, fid: impl GlobalVarId, value: Decimal) -> Result<()> {
1659 let fid = fid.var_id(self);
1660 assert!(self.get_var_type(fid) == ValueType::Decimal);
1661 unsafe { ffi::pbsession_SetDecGlobalVar(self.ptr, fid, self.new_pbdec(value)).into() }
1662 }
1663
1664 #[cfg(feature = "decimal")]
1674 pub unsafe fn set_var_dec_unchecked(&mut self, fid: impl GlobalVarId, value: Decimal) -> Result<()> {
1675 ffi::pbsession_SetDecGlobalVar(self.ptr, fid.var_id(self), self.new_pbdec(value)).into()
1676 }
1677
1678 pub fn set_var_str(&mut self, fid: impl GlobalVarId, value: impl AsPBStr) -> Result<()> {
1684 let fid = fid.var_id(self);
1685 assert!(self.get_var_type(fid) == ValueType::String);
1686 unsafe { ffi::pbsession_SetStringGlobalVar(self.ptr, fid, value.as_pbstr().as_ptr()).into() }
1687 }
1688
1689 pub unsafe fn set_var_str_unchecked(&mut self, fid: impl GlobalVarId, value: impl AsPBStr) -> Result<()> {
1699 ffi::pbsession_SetStringGlobalVar(self.ptr, fid.var_id(self), value.as_pbstr().as_ptr()).into()
1700 }
1701
1702 pub fn set_var_bool(&mut self, fid: impl GlobalVarId, value: bool) -> Result<()> {
1708 let fid = fid.var_id(self);
1709 assert!(self.get_var_type(fid) == ValueType::Boolean);
1710 unsafe { ffi::pbsession_SetBoolGlobalVar(self.ptr, fid, value.into()).into() }
1711 }
1712
1713 pub unsafe fn set_var_bool_unchecked(&mut self, fid: impl GlobalVarId, value: bool) -> Result<()> {
1723 ffi::pbsession_SetBoolGlobalVar(self.ptr, fid.var_id(self), value.into()).into()
1724 }
1725
1726 pub fn set_var_blob(&mut self, fid: impl GlobalVarId, value: impl AsRef<[u8]>) -> Result<()> {
1732 let fid = fid.var_id(self);
1733 assert!(self.get_var_type(fid) == ValueType::Blob);
1734 unsafe { ffi::pbsession_SetBlobGlobalVar(self.ptr, fid, self.new_pbblob(value)).into() }
1735 }
1736
1737 pub unsafe fn set_var_blob_unchecked(
1747 &mut self,
1748 fid: impl GlobalVarId,
1749 value: impl AsRef<[u8]>
1750 ) -> Result<()> {
1751 let value = value.as_ref();
1752 if value.is_empty() {
1753 return Err(PBXRESULT::E_OUTOF_MEMORY);
1754 }
1755 ffi::pbsession_SetBlobGlobalVar(self.ptr, fid.var_id(self), self.new_pbblob(value)).into()
1756 }
1757
1758 #[cfg(feature = "datetime")]
1764 pub fn set_var_date(&mut self, fid: impl GlobalVarId, value: NaiveDate) -> Result<()> {
1765 let fid = fid.var_id(self);
1766 assert!(self.get_var_type(fid) == ValueType::Date);
1767 unsafe { ffi::pbsession_SetDateGlobalVar(self.ptr, fid, self.new_pbdate(value)).into() }
1768 }
1769
1770 #[cfg(feature = "datetime")]
1780 pub unsafe fn set_var_date_unchecked(&mut self, fid: impl GlobalVarId, value: NaiveDate) -> Result<()> {
1781 ffi::pbsession_SetDateGlobalVar(self.ptr, fid.var_id(self), self.new_pbdate(value)).into()
1782 }
1783
1784 #[cfg(feature = "datetime")]
1790 pub fn set_var_time(&mut self, fid: impl GlobalVarId, value: NaiveTime) -> Result<()> {
1791 let fid = fid.var_id(self);
1792 assert!(self.get_var_type(fid) == ValueType::Time);
1793 unsafe { ffi::pbsession_SetTimeGlobalVar(self.ptr, fid, self.new_pbtime(value)).into() }
1794 }
1795
1796 #[cfg(feature = "datetime")]
1806 pub unsafe fn set_var_time_unchecked(&mut self, fid: impl GlobalVarId, value: NaiveTime) -> Result<()> {
1807 ffi::pbsession_SetTimeGlobalVar(self.ptr, fid.var_id(self), self.new_pbtime(value)).into()
1808 }
1809
1810 #[cfg(feature = "datetime")]
1816 pub fn set_var_datetime(&mut self, fid: impl GlobalVarId, value: NaiveDateTime) -> Result<()> {
1817 let fid = fid.var_id(self);
1818 assert!(self.get_var_type(fid) == ValueType::DateTime);
1819 unsafe { ffi::pbsession_SetDateTimeGlobalVar(self.ptr, fid, self.new_pbdatetime(value)).into() }
1820 }
1821
1822 #[cfg(feature = "datetime")]
1832 pub unsafe fn set_var_datetime_unchecked(
1833 &mut self,
1834 fid: impl GlobalVarId,
1835 value: NaiveDateTime
1836 ) -> Result<()> {
1837 ffi::pbsession_SetDateTimeGlobalVar(self.ptr, fid.var_id(self), self.new_pbdatetime(value)).into()
1838 }
1839
1840 pub fn set_var_char(&mut self, fid: impl GlobalVarId, value: PBChar) -> Result<()> {
1846 let fid = fid.var_id(self);
1847 assert!(self.get_var_type(fid) == ValueType::Char);
1848 unsafe { ffi::pbsession_SetCharGlobalVar(self.ptr, fid, value).into() }
1849 }
1850
1851 pub unsafe fn set_var_char_unchecked(&mut self, fid: impl GlobalVarId, value: PBChar) -> Result<()> {
1861 ffi::pbsession_SetCharGlobalVar(self.ptr, fid.var_id(self), value).into()
1862 }
1863
1864 pub fn set_var_byte(&mut self, fid: impl GlobalVarId, value: pbbyte) -> Result<()> {
1870 let fid = fid.var_id(self);
1871 assert!(self.get_var_type(fid) == ValueType::Byte);
1872 unsafe { ffi::pbsession_SetByteGlobalVar(self.ptr, fid, value).into() }
1873 }
1874
1875 pub unsafe fn set_var_byte_unchecked(&mut self, fid: impl GlobalVarId, value: pbbyte) -> Result<()> {
1885 ffi::pbsession_SetByteGlobalVar(self.ptr, fid.var_id(self), value).into()
1886 }
1887
1888 pub fn set_var_object(&mut self, fid: impl GlobalVarId, value: &Object) -> Result<()> {
1894 let fid = fid.var_id(self);
1895 assert!(self.is_var_object(fid));
1896 unsafe { ffi::pbsession_SetObjectGlobalVar(self.ptr, fid, value.as_ptr()).into() }
1897 }
1898
1899 pub unsafe fn set_var_object_unchecked(&mut self, fid: impl GlobalVarId, value: &Object) -> Result<()> {
1909 ffi::pbsession_SetObjectGlobalVar(self.ptr, fid.var_id(self), value.as_ptr()).into()
1910 }
1911
1912 pub fn set_var_array(&mut self, fid: impl GlobalVarId, value: &Array) -> Result<()> {
1918 let fid = fid.var_id(self);
1919 assert!(self.is_var_array(fid));
1920 unsafe { ffi::pbsession_SetArrayGlobalVar(self.ptr, fid, value.as_ptr()).into() }
1921 }
1922
1923 pub unsafe fn set_var_array_unchecked(&mut self, fid: impl GlobalVarId, value: &Array) -> Result<()> {
1933 ffi::pbsession_SetArrayGlobalVar(self.ptr, fid.var_id(self), value.as_ptr()).into()
1934 }
1935}
1936
1937pub trait AsMethodName {
1943 fn as_method_name(&self) -> (Cow<'_, PBStr>, Cow<'_, PBStr>);
1944}
1945
1946impl<T: AsPBStr> AsMethodName for T {
1947 #[inline]
1948 fn as_method_name(&self) -> (Cow<'_, PBStr>, Cow<'_, PBStr>) { (self.as_pbstr(), "".as_pbstr()) }
1949}
1950
1951impl<T: AsPBStr, S: AsPBStr> AsMethodName for (T, S) {
1952 #[inline]
1953 fn as_method_name(&self) -> (Cow<'_, PBStr>, Cow<'_, PBStr>) {
1954 let (name, sign) = self;
1955 (name.as_pbstr(), sign.as_pbstr())
1956 }
1957}
1958
1959#[derive(Clone, Copy)]
1961pub struct GlobalFunctionId {
1962 pub(crate) cls: pbclass,
1963 pub(crate) mid: MethodId
1964}
1965
1966pub trait AsGlobalFunctionId {
1968 fn as_mid(&self, session: &Session) -> Result<GlobalFunctionId>;
1969}
1970
1971impl<T: AsMethodName> AsGlobalFunctionId for T {
1972 #[inline]
1973 fn as_mid(&self, session: &Session) -> Result<GlobalFunctionId> {
1974 session.get_function_id(self.as_method_name()).ok_or(PBXRESULT::E_INVALID_METHOD_ID)
1975 }
1976}
1977impl AsGlobalFunctionId for GlobalFunctionId {
1978 #[inline]
1979 fn as_mid(&self, _session: &Session) -> Result<GlobalFunctionId> { Ok(*self) }
1980}
1981impl AsGlobalFunctionId for Option<GlobalFunctionId> {
1982 #[inline]
1983 fn as_mid(&self, _session: &Session) -> Result<GlobalFunctionId> {
1984 self.ok_or(PBXRESULT::E_INVALID_METHOD_ID)
1985 }
1986}
1987
1988impl Session {
1989 pub fn get_user_function_id(&self, name: impl AsMethodName) -> Option<GlobalFunctionId> {
1999 let (name, sign) = name.as_method_name();
2000 if let Some(group) = self.find_group(name.as_ref(), GroupType::Function) {
2001 self.find_class(group, name.as_ref()).and_then(|cls| {
2002 self.get_method_id(cls, name.as_ref(), RoutineType::Function, sign, true).map(|mid| {
2003 GlobalFunctionId {
2004 cls,
2005 mid
2006 }
2007 })
2008 })
2009 } else {
2010 None
2011 }
2012 }
2013
2014 pub fn get_system_function_id(&self, name: impl AsMethodName) -> Option<GlobalFunctionId> {
2026 let (name, sign) = name.as_method_name();
2027 self.find_class(self.get_system_group(), "SystemFunctions").and_then(|cls| {
2028 self.get_method_id(cls, name, RoutineType::Function, sign, true).map(|mid| {
2029 GlobalFunctionId {
2030 cls,
2031 mid
2032 }
2033 })
2034 })
2035 }
2036
2037 pub fn get_function_id(&self, name: impl AsMethodName) -> Option<GlobalFunctionId> {
2049 let (name, sign) = name.as_method_name();
2050 self.get_user_function_id((name.as_ref(), sign.as_ref()))
2051 .or_else(|| self.get_system_function_id((name, sign)))
2052 }
2053
2054 pub fn invoke_function<F, R>(&self, mid: impl AsGlobalFunctionId, arg_cb: F) -> Result<R>
2062 where
2063 F: FnOnce(Arguments) -> Result<()>,
2064 R: FromValueOwned
2065 {
2066 let invoker = self.begin_invoke_function(mid)?;
2067 arg_cb(invoker.args())?;
2068 let rv = invoker.invoke()?;
2069 R::from_value(Some(rv))
2070 }
2071
2072 pub fn begin_invoke_function<'a>(
2083 &'a self,
2084 mid: impl AsGlobalFunctionId
2085 ) -> Result<Invoker<GlobalFunction<'a>>> {
2086 let mid = mid.as_mid(self)?;
2087 let ci = unsafe { CallInfo::new(mid.cls, mid.mid, self.clone())? };
2088 Ok(Invoker::<GlobalFunction>::new(GlobalFunction::new(mid.cls), ci))
2089 }
2090
2091 pub(crate) fn get_method_id(
2092 &self,
2093 cls: pbclass,
2094 methodName: impl AsPBStr,
2095 rt: RoutineType,
2096 signature: impl AsPBStr,
2097 publicOnly: bool
2098 ) -> Option<MethodId> {
2099 unsafe {
2100 let mid = ffi::pbsession_GetMethodID(
2101 self.ptr,
2102 cls,
2103 methodName.as_pbstr().as_ptr(),
2104 rt,
2105 signature.as_pbstr().as_ptr(),
2106 publicOnly.into()
2107 );
2108 if mid.is_undefined() {
2109 None
2110 } else {
2111 Some(mid)
2112 }
2113 }
2114 }
2115 pub(crate) fn find_matching_function(
2116 &self,
2117 cls: pbclass,
2118 methodName: impl AsPBStr,
2119 rt: RoutineType,
2120 readableSignature: impl AsPBStr
2121 ) -> Option<MethodId> {
2122 unsafe {
2123 let mid = ffi::pbsession_FindMatchingFunction(
2124 self.ptr,
2125 cls,
2126 methodName.as_pbstr().as_ptr(),
2127 rt,
2128 readableSignature.as_pbstr().as_ptr()
2129 );
2130 if mid.is_undefined() {
2131 None
2132 } else {
2133 Some(mid)
2134 }
2135 }
2136 }
2137 pub(crate) fn get_method_id_by_event_id(&self, cls: pbclass, eventID: impl AsPBStr) -> Option<MethodId> {
2138 unsafe {
2139 let mid = ffi::pbsession_GetMethodIDByEventID(self.ptr, cls, eventID.as_pbstr().as_ptr());
2140 if mid.is_undefined() {
2141 None
2142 } else {
2143 Some(mid)
2144 }
2145 }
2146 }
2147}
2148
2149pub struct OwnedSession<'vm> {
2153 session: Session,
2154 _marker: PhantomData<&'vm ()>
2155}
2156
2157impl<'vm> OwnedSession<'vm> {
2158 pub(crate) unsafe fn from_ptr(ptr: pbsession) -> OwnedSession<'vm> {
2159 OwnedSession {
2160 session: Session::from_ptr(ptr),
2161 _marker: PhantomData
2162 }
2163 }
2164
2165 pub fn set_debug_trace(&self, traceFile: impl AsPBStr) {
2167 unsafe { ffi::pbsession_SetDebugTrace(self.session.ptr, traceFile.as_pbstr().as_ptr()) }
2168 }
2169
2170 pub fn release(self) {}
2172}
2173
2174impl Drop for OwnedSession<'_> {
2175 fn drop(&mut self) { unsafe { ffi::pbsession_Release(self.session.ptr) } }
2176}
2177
2178impl Deref for OwnedSession<'_> {
2179 type Target = Session;
2180 fn deref(&self) -> &Self::Target { &self.session }
2181}
2182
2183#[must_use]
2197pub struct LocalFrame<'session> {
2198 session: &'session Session
2199}
2200
2201impl<'session> LocalFrame<'session> {
2202 pub fn new(session: &Session) -> LocalFrame {
2204 unsafe { ffi::pbsession_PushLocalFrame(session.ptr) }
2205 LocalFrame {
2206 session
2207 }
2208 }
2209 pub fn pop(self) {}
2211}
2212
2213impl<'session> Drop for LocalFrame<'session> {
2214 fn drop(&mut self) { unsafe { ffi::pbsession_PopLocalFrame(self.session.ptr) } }
2215}
2216
2217