pbni/
session.rs

1use crate::{bindings::*, invoker::GlobalFunction, value::FromValueOwned, *};
2use std::{borrow::Cow, ops::Deref};
3
4/// Session对象
5#[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    /// 克隆Session对象
19    ///
20    /// # Safety
21    ///
22    /// 此方法不能延长Session对象的生命周期,因此不能保证克隆后的Session对象始终有效,生命周期将始终与此对象一样
23    pub unsafe fn clone(&self) -> Session {
24        Session {
25            ptr: self.ptr
26        }
27    }
28
29    /// 判断是否有重启Session的请求 (在PowerScript中调用了`Restart`函数)
30    pub fn restart_requested(&self) -> bool { unsafe { ffi::pbsession_RestartRequested(self.ptr).into() } }
31
32    /// 是否创建了可视化对象 (打开了顶层窗口)
33    pub fn has_visual_object(&self) -> bool { unsafe { ffi::pbsession_HasPBVisualObject(self.ptr).into() } }
34
35    /// 处理PB消息
36    ///
37    /// # Notice
38    ///
39    /// 开启了消息循环后,需要处理PB的消息以执行PowerScript中的`Post`调用
40    pub fn process_message(&self) -> bool { unsafe { ffi::pbsession_ProcessPBMessage(self.ptr).into() } }
41
42    /// 获取系统类组
43    pub(crate) fn get_system_group(&self) -> pbgroup { unsafe { ffi::pbsession_GetSystemGroup(self.ptr) } }
44
45    /// 查找指定名称的类组
46    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    /// 在指定组下查找类定义
51    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    /// 获取类定义的组
56    ///
57    /// FIXME: 此方法通过类名反查类所在的组,目前PBNI没有提供直接的获取方法
58    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    /*
77        Exception
78    */
79
80    /// 检查当前是否有异常未处理
81    pub fn has_exception(&self) -> bool { unsafe { ffi::pbsession_HasExceptionThrown(self.ptr).into() } }
82
83    /// 清除异常
84    pub fn clear_exception(&self) {
85        unsafe {
86            ffi::pbsession_ClearException(self.ptr);
87        }
88    }
89
90    /// 抛出`PBXRuntimeError`异常
91    ///
92    /// # Exmaples
93    ///
94    /// ```
95    /// session.throw_exception("test");
96    /// // 使用宏
97    /// throw!(session,"this is a {}!","exception");
98    /// ```
99    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    /*
109        Prop
110    */
111
112    /// 与Session绑定`static`引用参数
113    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    /// 与Session绑定指针参数
122    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    /// 获取Session绑定的指针参数
131    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    /// 获取Session绑定的引用参数
139    ///
140    ///
141    /// # Safety
142    ///
143    /// 引用的生命周期由调用处提供,需要开发者自行保证期有效性
144    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    /// 获取Session绑定的可变引用参数
158    ///
159    ///
160    /// # Safety
161    ///
162    /// 引用的生命周期由调用处提供,需要开发者自行保证期有效性
163    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    /// 解绑Session参数
177    ///
178    /// # Notice
179    ///
180    /// 如果绑定的参数内存是由`Box`分配的,那么需要在解绑前正确释放内存
181    pub fn remove_prop(&self, name: impl AsPBStr) {
182        unsafe { ffi::pbsession_RemoveProp(self.ptr, name.as_pbstr().as_ptr()) }
183    }
184
185    /*
186        Enum
187    */
188
189    /// 获取指定名称枚举的值,不区分大小写
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// // `Center!`枚举的值
195    /// session.get_enum_item_value("Aligment","Center");
196    /// ```
197    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    /// 获取枚举值的枚举名称,不区分大小写
208    ///
209    /// # Examples
210    ///
211    /// ```
212    /// let val = session.get_enum_item_value("Aligment","Center");
213    /// let name = session.get_enum_item_name("Aligment",val); //center
214    /// ```
215    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    /*
231        String
232    */
233
234    #[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    /*
245        Object
246    */
247
248    /// 实例化用户自定义对象
249    ///
250    /// # Examples
251    ///
252    /// ```
253    /// let obj = session.new_user_object("n_cst_object");
254    /// ```
255    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    /// 实例化系统对象
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// let obj = session.new_system_object("datastore");
273    /// ```
274    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    /// 实例化任意PB对象 (包括用户自定义对象和系统对象)
284    ///
285    /// # Examples
286    ///
287    /// ```
288    /// let obj = session.new_object("n_cst_object");
289    /// let obj = session.new_object("datastore");
290    /// ```
291    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    /*
297        Array
298    */
299
300    /// 实例化变长标量一维数组
301    ///
302    /// # Parameters
303    ///
304    /// - **item_type** 元素标量类型
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// //int arr[]
310    /// let mut arr = session.new_array(ValueType::Int).unwrap();
311    /// //arr[1] = 123
312    /// arr.set_item_int(&[1],123);
313    /// ```
314    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    /// 实例化定长标量多维数组
323    ///
324    /// # Parameters
325    ///
326    /// - **item_type** 元素标量类型
327    /// - **dims** `&[(下标,上标)]`
328    ///
329    /// # Examples
330    ///
331    /// ```
332    /// //int arr[10]
333    /// let mut arr = session.new_bounded_array(ValueType::Int,&[(1,10)]).unwrap();
334    /// //arr[1] = 123
335    /// arr.set_item_int(&[1],123);
336    ///
337    /// //int arr[2,4]
338    /// let mut arr = session.new_bounded_array(ValueType::Int,&[(1,2),(1,4)]).unwrap();
339    /// //arr[1,2] = 123
340    /// arr.set_item_int(&[1,2],123);
341    ///
342    /// //int arr[1 to 5,2 to 10]
343    /// let mut arr = session.new_bounded_array(ValueType::Int,&[(1,5),(2,10)]).unwrap();
344    /// //arr[1,2] = 123
345    /// arr.set_item_int(&[1,2],123);
346    /// ```
347    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    /// 实例化变长用户自定义对象一维数组
370    ///
371    /// # Parameters
372    ///
373    /// - **cls_name** 元素对象类名
374    ///
375    /// # Examples
376    ///
377    /// ```
378    /// //n_cst_test arr[]
379    /// let mut arr = session.new_user_object_array("n_cst_test").unwrap();
380    /// //arr[1] = Create n_cst_test
381    /// let obj = session.new_user_object("n_cst_test").unwrap();
382    /// arr.set_item_object(&[1],&obj);
383    /// ```
384    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    /// 实例化变长系统对象一维数组
393    ///
394    /// # Parameters
395    ///
396    /// - **cls_name** 元素对象类名
397    ///
398    /// # Examples
399    ///
400    /// ```
401    /// //datastore arr[]
402    /// let mut arr = session.new_system_object_array("datastore").unwrap();
403    /// //arr[1] = Create datastore
404    /// let obj = session.new_user_object("datastore").unwrap();
405    /// arr.set_item_object(&[1],&obj);
406    /// ```
407    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    /// 实例化变长任意对象一维数组 (包括用户自定义对象和系统对象)
414    ///
415    /// # Parameters
416    ///
417    /// - **cls_name** 元素对象类名
418    ///
419    /// # Examples
420    ///
421    /// ```
422    /// //datastore arr[]
423    /// let mut arr = session.new_object_array("datastore").unwrap();
424    /// //arr[1] = Create datastore
425    /// let obj = session.new_user_object("datastore").unwrap();
426    /// arr.set_item_object(&[1],&obj);
427    /// ```
428    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    /// 实例化定长用户自定义对象多维数组
442    ///
443    /// # Parameters
444    ///
445    /// - **cls_name** 元素对象类名
446    /// - **dims** `&[(下标,上标)]`
447    ///
448    /// # Examples
449    ///
450    /// ```
451    /// //n_cst_test arr[10]
452    /// let mut arr = session.new_bounded_user_object_array("n_cst_test",&[(1,10)]).unwrap();
453    /// //arr[1] = Create n_cst_test
454    /// let obj = session.new_user_object("n_cst_test").unwrap();
455    /// arr.set_item_object(&[1],&obj);
456    ///
457    /// //n_cst_test arr[2,4]
458    /// let mut arr = session.new_bounded_user_object_array("n_cst_test",&[(1,2),(1,4)]).unwrap();
459    /// //arr[1,2] = Create n_cst_test
460    /// let obj = session.new_user_object("n_cst_test").unwrap();
461    /// arr.set_item_object(&[1,2],&obj);
462    ///
463    /// //n_cst_test arr[1 to 5,2 to 10]
464    /// let mut arr = session.new_bounded_user_object_array("n_cst_test",&[(1,5),(2,10)]).unwrap();
465    /// //arr[1,2] = Create n_cst_test
466    /// arr.set_item_object(&[1,2],&obj);
467    /// ```
468    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    /// 实例化定长用户自定义对象多维数组
481    ///
482    /// # Parameters
483    ///
484    /// - **cls_name** 元素对象类名
485    /// - **dims** `&[(下标,上标)]`
486    ///
487    /// # Examples
488    ///
489    /// ```
490    /// //datastore arr[10]
491    /// let mut arr = session.new_bounded_system_object_array("datastore",&[(1,10)]).unwrap();
492    /// //arr[1] = Create datastore
493    /// let obj = session.new_user_object("datastore").unwrap();
494    /// arr.set_item_object(&[1],&obj);
495    ///
496    /// //datastore arr[2,4]
497    /// let mut arr = session.new_bounded_system_object_array("datastore",&[(1,2),(1,4)]).unwrap();
498    /// //arr[1,2] = Create datastore
499    /// let obj = session.new_user_object("datastore").unwrap();
500    /// arr.set_item_object(&[1,2],&obj);
501    ///
502    /// //datastore arr[1 to 5,2 to 10]
503    /// let mut arr = session.new_bounded_system_object_array("datastore",&[(1,5),(2,10)]).unwrap();
504    /// //arr[1,2] = Create datastore
505    /// arr.set_item_object(&[1,2],&obj);
506    /// ```
507    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    /// 实例化定长任意对象多维数组
518    ///
519    /// # Parameters
520    ///
521    /// - **cls_name** 元素对象类名
522    /// - **dims** `&[(下标,上标)]`
523    ///
524    /// # Examples
525    ///
526    /// ```
527    /// //datastore arr[10]
528    /// let mut arr = session.new_bounded_object_array("datastore",&[(1,10)]).unwrap();
529    /// //arr[1] = Create datastore
530    /// let obj = session.new_user_object("datastore").unwrap();
531    /// arr.set_item_object(&[1],&obj);
532    ///
533    /// //datastore arr[2,4]
534    /// let mut arr = session.new_bounded_object_array("datastore",&[(1,2),(1,4)]).unwrap();
535    /// //arr[1,2] = Create datastore
536    /// let obj = session.new_user_object("datastore").unwrap();
537    /// arr.set_item_object(&[1,2],&obj);
538    ///
539    /// //datastore arr[1 to 5,2 to 10]
540    /// let mut arr = session.new_bounded_object_array("datastore",&[(1,5),(2,10)]).unwrap();
541    /// //arr[1,2] = Create datastore
542    /// arr.set_item_object(&[1,2],&obj);
543    /// ```
544    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    /*
576        Blob
577    */
578
579    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    /*
595        Date, Time and DateTime
596    */
597
598    #[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    /*
700        Decimal number
701    */
702    #[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
721/*
722    Global variable
723*/
724
725/// 全局变量ID抽象
726pub 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    /// 获取全局变量ID
751    ///
752    /// # Examples
753    ///
754    /// ```
755    /// let fid = session.get_var_id("gs_var").unwrap();
756    /// session.set_var_str(fid,"rust");
757    /// ```
758    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    /// 判断是否存在指定全局变量
770    ///
771    /// # Examples
772    ///
773    /// ```
774    /// if session.has_var("gs_var") {
775    ///     session.set_var_str("gs_var","rust");
776    /// }
777    /// ```
778    pub fn has_var(&self, name: impl AsPBStr) -> bool { self.get_var_id(name).is_some() }
779
780    /// 获取指定全局变量类型
781    ///
782    /// # Panics
783    ///
784    /// 访问不存在的变量时会触发Panic
785    ///
786    /// # Examples
787    ///
788    /// ```
789    /// if session.get_var_type("gs_var") == ValueType::String {
790    ///     session.set_var_str("gs_var","rust");
791    /// }
792    /// ```
793    pub fn get_var_type(&self, fid: impl GlobalVarId) -> ValueType {
794        unsafe { ffi::pbsession_GetGlobalVarType(self.ptr, fid.var_id(self)) }
795    }
796
797    /// 判断指定全局变量是否为NULL
798    ///
799    /// # Panics
800    ///
801    /// 访问不存在的变量时会触发Panic
802    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    /// 判断指定全局变量是否为数组类型
807    ///
808    /// # Panics
809    ///
810    /// 访问不存在的变量时会触发Panic
811    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    /// 判断指定全局变量是否为对象类型
816    ///
817    /// # Panics
818    ///
819    /// 访问不存在的变量时会触发Panic
820    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    /// 获取`int`类型全局变量值
825    ///
826    /// # Panics
827    ///
828    /// 访问不存在的变量或类型不匹配时会触发Panic
829    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    /// 获取`int`类型全局变量值,不检查类型
836    ///
837    /// # Panics
838    ///
839    /// 访问不存在的变量时会触发Panic
840    ///
841    /// # Safety
842    ///
843    /// 类型不兼容时可能会出现未定义行为
844    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    /// 获取`uint`类型全局变量值
855    ///
856    /// # Panics
857    ///
858    /// 访问不存在的变量或类型不匹配时会触发Panic
859    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    /// 获取`uint`类型全局变量值,不检查类型
866    ///
867    /// # Panics
868    ///
869    /// 访问不存在的变量时会触发Panic
870    ///
871    /// # Safety
872    ///
873    /// 类型不兼容时可能会出现未定义行为
874    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    /// 获取`long`类型全局变量值
885    ///
886    /// # Panics
887    ///
888    /// 访问不存在的变量或类型不匹配时会触发Panic
889    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    /// 获取`long`类型全局变量值,不检查类型
896    ///
897    /// # Panics
898    ///
899    /// 访问不存在的变量时会触发Panic
900    ///
901    /// # Safety
902    ///
903    /// 类型不兼容时可能会出现未定义行为
904    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    /// 获取`ulong`类型全局变量值
915    ///
916    /// # Panics
917    ///
918    /// 访问不存在的变量或类型不匹配时会触发Panic
919    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    /// 获取`ulong`类型全局变量值,不检查类型
926    ///
927    /// # Panics
928    ///
929    /// 访问不存在的变量时会触发Panic
930    ///
931    /// # Safety
932    ///
933    /// 类型不兼容时可能会出现未定义行为
934    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    /// 获取`longlong`类型全局变量值
945    ///
946    /// # Panics
947    ///
948    /// 访问不存在的变量或类型不匹配时会触发Panic
949    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    /// 获取`longlong`类型全局变量值,不检查类型
956    ///
957    /// # Panics
958    ///
959    /// 访问不存在的变量时会触发Panic
960    ///
961    /// # Safety
962    ///
963    /// 类型不兼容时可能会出现未定义行为
964    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    /// 获取`real`类型全局变量值
975    ///
976    /// # Panics
977    ///
978    /// 访问不存在的变量或类型不匹配时会触发Panic
979    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    /// 获取`real`类型全局变量值,不检查类型
986    ///
987    /// # Panics
988    ///
989    /// 访问不存在的变量时会触发Panic
990    ///
991    /// # Safety
992    ///
993    /// 类型不兼容时可能会出现未定义行为
994    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    /// 获取`double`类型全局变量值
1005    ///
1006    /// # Panics
1007    ///
1008    /// 访问不存在的变量或类型不匹配时会触发Panic
1009    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    /// 获取`double`类型全局变量值,不检查类型
1016    ///
1017    /// # Panics
1018    ///
1019    /// 访问不存在的变量时会触发Panic
1020    ///
1021    /// # Safety
1022    ///
1023    /// 类型不兼容时可能会出现未定义行为
1024    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    /// 获取`decimal`类型全局变量值
1035    ///
1036    /// # Panics
1037    ///
1038    /// 访问不存在的变量或类型不匹配时会触发Panic
1039    #[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    /// 获取`decimal`类型全局变量值,不检查类型
1047    ///
1048    /// # Panics
1049    ///
1050    /// 访问不存在的变量时会触发Panic
1051    ///
1052    /// # Safety
1053    ///
1054    /// 类型不兼容时可能会出现未定义行为
1055    #[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    /// 获取`string`类型全局变量的引用
1067    ///
1068    /// # Panics
1069    ///
1070    /// 访问不存在的变量或类型不匹配时会触发Panic
1071    ///
1072    /// # Safety
1073    ///
1074    /// 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1075    ///
1076    /// [内存安全]: ./index.html#内存安全
1077    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    /// 获取`string`类型全局变量的引用,不检查类型
1084    ///
1085    /// # Panics
1086    ///
1087    /// 访问不存在的变量时会触发Panic
1088    ///
1089    /// # Safety
1090    ///
1091    /// - 类型不兼容时可能会出现未定义行为
1092    /// - 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1093    ///
1094    /// [内存安全]: ./index.html#内存安全
1095    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    /// 获取`string`类型全局变量值
1106    ///
1107    /// # Panics
1108    ///
1109    /// 访问不存在的变量或类型不匹配时会触发Panic
1110    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    /// 获取`string`类型全局变量值,不检查类型
1117    ///
1118    /// # Panics
1119    ///
1120    /// 访问不存在的变量时会触发Panic
1121    ///
1122    /// # Safety
1123    ///
1124    /// 类型不兼容时可能会出现未定义行为
1125    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    /// 获取`boolean`类型全局变量值
1130    ///
1131    /// # Panics
1132    ///
1133    /// 访问不存在的变量或类型不匹配时会触发Panic
1134    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    /// 获取`boolean`类型全局变量值,不检查类型
1141    ///
1142    /// # Panics
1143    ///
1144    /// 访问不存在的变量时会触发Panic
1145    ///
1146    /// # Safety
1147    ///
1148    /// 类型不兼容时可能会出现未定义行为
1149    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    /// 获取`blob`类型全局变量的引用
1160    ///
1161    /// # Panics
1162    ///
1163    /// 访问不存在的变量或类型不匹配时会触发Panic
1164    ///
1165    /// # Safety
1166    ///
1167    /// 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1168    ///
1169    /// [内存安全]: ./index.html#内存安全
1170    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    /// 获取`blob`类型全局变量的引用,不检查类型
1177    ///
1178    /// # Panics
1179    ///
1180    /// 访问不存在的变量时会触发Panic
1181    ///
1182    /// # Safety
1183    ///
1184    /// - 类型不兼容时可能会出现未定义行为
1185    /// - 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1186    ///
1187    /// [内存安全]: ./index.html#内存安全
1188    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    /// 获取`date`类型全局变量值
1199    ///
1200    /// # Panics
1201    ///
1202    /// 访问不存在的变量或类型不匹配时会触发Panic
1203    #[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    /// 获取`date`类型全局变量值,不检查类型
1211    ///
1212    /// # Panics
1213    ///
1214    /// 访问不存在的变量时会触发Panic
1215    ///
1216    /// # Safety
1217    ///
1218    /// 类型不兼容时可能会出现未定义行为
1219    #[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    /// 获取`time`类型全局变量值
1231    ///
1232    /// # Panics
1233    ///
1234    /// 访问不存在的变量或类型不匹配时会触发Panic
1235    #[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    /// 获取`time`类型全局变量值,不检查类型
1243    ///
1244    /// # Panics
1245    ///
1246    /// 访问不存在的变量时会触发Panic
1247    ///
1248    /// # Safety
1249    ///
1250    /// 类型不兼容时可能会出现未定义行为
1251    #[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    /// 获取`datetime`类型全局变量值
1263    ///
1264    /// # Panics
1265    ///
1266    /// 访问不存在的变量或类型不匹配时会触发Panic
1267    #[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    /// 获取`datetime`类型全局变量值,不检查类型
1275    ///
1276    /// # Panics
1277    ///
1278    /// 访问不存在的变量时会触发Panic
1279    ///
1280    /// # Safety
1281    ///
1282    /// 类型不兼容时可能会出现未定义行为
1283    #[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    /// 获取`char`类型全局变量值
1295    ///
1296    /// # Panics
1297    ///
1298    /// 访问不存在的变量或类型不匹配时会触发Panic
1299    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    /// 获取`char`类型全局变量值,不检查类型
1306    ///
1307    /// # Panics
1308    ///
1309    /// 访问不存在的变量时会触发Panic
1310    ///
1311    /// # Safety
1312    ///
1313    /// 类型不兼容时可能会出现未定义行为
1314    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    /// 获取`byte`类型全局变量值
1325    ///
1326    /// # Panics
1327    ///
1328    /// 访问不存在的变量或类型不匹配时会触发Panic
1329    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    /// 获取`byte`类型全局变量值,不检查类型
1336    ///
1337    /// # Panics
1338    ///
1339    /// 访问不存在的变量时会触发Panic
1340    ///
1341    /// # Safety
1342    ///
1343    /// 类型不兼容时可能会出现未定义行为
1344    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    /// 获取对象类型全局变量的引用
1355    ///
1356    /// # Panics
1357    ///
1358    /// 访问不存在的变量或类型不匹配时会触发Panic
1359    ///
1360    /// # Safety
1361    ///
1362    /// 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1363    ///
1364    /// [内存安全]: ./index.html#内存安全
1365    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    /// 获取对象类型全局变量的引用,不检查类型
1372    ///
1373    /// # Panics
1374    ///
1375    /// 访问不存在的变量时会触发Panic
1376    ///
1377    /// # Safety
1378    ///
1379    /// - 类型不兼容时可能会出现未定义行为
1380    /// - 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1381    ///
1382    /// [内存安全]: ./index.html#内存安全
1383    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    /// 获取数组类型全局变量的引用
1394    ///
1395    /// # Panics
1396    ///
1397    /// 访问不存在的变量或类型不匹配时会触发Panic
1398    ///
1399    /// # Safety
1400    ///
1401    /// 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1402    ///
1403    /// [内存安全]: ./index.html#内存安全
1404    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    /// 获取数组类型全局变量的引用,不检查类型
1411    ///
1412    /// # Panics
1413    ///
1414    /// 访问不存在的变量时会触发Panic
1415    ///
1416    /// # Safety
1417    ///
1418    /// - 类型不兼容时可能会出现未定义行为
1419    /// - 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1420    ///
1421    /// [内存安全]: ./index.html#内存安全
1422    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    /// 获取`any`类型全局变量的引用
1433    ///
1434    /// # Panics
1435    ///
1436    /// 访问不存在的变量或类型不匹配时会触发Panic
1437    ///
1438    /// # Safety
1439    ///
1440    /// 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1441    ///
1442    /// [内存安全]: ./index.html#内存安全
1443    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    /// 获取`any`类型全局变量的引用,不检查类型
1450    ///
1451    /// # Panics
1452    ///
1453    /// 访问不存在的变量时会触发Panic
1454    ///
1455    /// # Safety
1456    ///
1457    /// - 类型不兼容时可能会出现未定义行为
1458    /// - 引用类型不能保证始终有效,详情请阅读[内存安全]说明
1459    ///
1460    /// [内存安全]: ./index.html#内存安全
1461    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    /// 设置全局变量的值为NULL
1472    ///
1473    /// # Panics
1474    ///
1475    /// 访问不存在的变量时会触发Panic
1476    pub fn set_var_to_null(&self, fid: impl GlobalVarId) {
1477        unsafe { ffi::pbsession_SetGlobalVarToNull(self.ptr, fid.var_id(self)) }
1478    }
1479
1480    /// 设置`int`类型全局变量的值
1481    ///
1482    /// # Panics
1483    ///
1484    /// 访问不存在的变量或类型不匹配时会触发Panic
1485    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    /// 设置`int`类型全局变量的值,不检查类型
1492    ///
1493    /// # Panics
1494    ///
1495    /// 访问不存在的变量时会触发Panic
1496    ///
1497    /// # Safety
1498    ///
1499    /// 类型不兼容时可能会出现未定义行为
1500    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    /// 设置`uint`类型全局变量的值
1505    ///
1506    /// # Panics
1507    ///
1508    /// 访问不存在的变量或类型不匹配时会触发Panic
1509    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    /// 设置`uint`类型全局变量的值,不检查类型
1516    ///
1517    /// # Panics
1518    ///
1519    /// 访问不存在的变量时会触发Panic
1520    ///
1521    /// # Safety
1522    ///
1523    /// 类型不兼容时可能会出现未定义行为
1524    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    /// 设置`long`类型全局变量的值
1529    ///
1530    /// # Panics
1531    ///
1532    /// 访问不存在的变量或类型不匹配时会触发Panic
1533    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    /// 设置`long`类型全局变量的值,不检查类型
1540    ///
1541    /// # Panics
1542    ///
1543    /// 访问不存在的变量时会触发Panic
1544    ///
1545    /// # Safety
1546    ///
1547    /// 类型不兼容时可能会出现未定义行为
1548    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    /// 设置`ulong`类型全局变量的值
1553    ///
1554    /// # Panics
1555    ///
1556    /// 访问不存在的变量或类型不匹配时会触发Panic
1557    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    /// 设置`ulong`类型全局变量的值,不检查类型
1564    ///
1565    /// # Panics
1566    ///
1567    /// 访问不存在的变量时会触发Panic
1568    ///
1569    /// # Safety
1570    ///
1571    /// 类型不兼容时可能会出现未定义行为
1572    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    /// 设置`longlong`类型全局变量的值
1577    ///
1578    /// # Panics
1579    ///
1580    /// 访问不存在的变量或类型不匹配时会触发Panic
1581    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    /// 设置`longlong`类型全局变量的值,不检查类型
1588    ///
1589    /// # Panics
1590    ///
1591    /// 访问不存在的变量时会触发Panic
1592    ///
1593    /// # Safety
1594    ///
1595    /// 类型不兼容时可能会出现未定义行为
1596    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    /// 设置`real`类型全局变量的值
1605    ///
1606    /// # Panics
1607    ///
1608    /// 访问不存在的变量或类型不匹配时会触发Panic
1609    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    /// 设置`real`类型全局变量的值,不检查类型
1616    ///
1617    /// # Panics
1618    ///
1619    /// 访问不存在的变量时会触发Panic
1620    ///
1621    /// # Safety
1622    ///
1623    /// 类型不兼容时可能会出现未定义行为
1624    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    /// 设置`double`类型全局变量的值
1629    ///
1630    /// # Panics
1631    ///
1632    /// 访问不存在的变量或类型不匹配时会触发Panic
1633    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    /// 设置`double`类型全局变量的值,不检查类型
1640    ///
1641    /// # Panics
1642    ///
1643    /// 访问不存在的变量时会触发Panic
1644    ///
1645    /// # Safety
1646    ///
1647    /// 类型不兼容时可能会出现未定义行为
1648    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    /// 设置`decimal`类型全局变量的值
1653    ///
1654    /// # Panics
1655    ///
1656    /// 访问不存在的变量或类型不匹配时会触发Panic
1657    #[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    /// 设置`decimal`类型全局变量的值,不检查类型
1665    ///
1666    /// # Panics
1667    ///
1668    /// 访问不存在的变量时会触发Panic
1669    ///
1670    /// # Safety
1671    ///
1672    /// 类型不兼容时可能会出现未定义行为
1673    #[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    /// 设置`string`类型全局变量的值
1679    ///
1680    /// # Panics
1681    ///
1682    /// 访问不存在的变量或类型不匹配时会触发Panic
1683    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    /// 设置`string`类型全局变量的值,不检查类型
1690    ///
1691    /// # Panics
1692    ///
1693    /// 访问不存在的变量时会触发Panic
1694    ///
1695    /// # Safety
1696    ///
1697    /// 类型不兼容时可能会出现未定义行为
1698    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    /// 设置`boolean`类型全局变量的值
1703    ///
1704    /// # Panics
1705    ///
1706    /// 访问不存在的变量或类型不匹配时会触发Panic
1707    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    /// 设置`boolean`类型全局变量的值,不检查类型
1714    ///
1715    /// # Panics
1716    ///
1717    /// 访问不存在的变量时会触发Panic
1718    ///
1719    /// # Safety
1720    ///
1721    /// 类型不兼容时可能会出现未定义行为
1722    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    /// 设置`blob`类型全局变量的值
1727    ///
1728    /// # Panics
1729    ///
1730    /// 访问不存在的变量或类型不匹配时会触发Panic
1731    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    /// 设置`blob`类型全局变量的值,不检查类型
1738    ///
1739    /// # Panics
1740    ///
1741    /// 访问不存在的变量时会触发Panic
1742    ///
1743    /// # Safety
1744    ///
1745    /// 类型不兼容时可能会出现未定义行为
1746    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    /// 设置`date`类型全局变量的值
1759    ///
1760    /// # Panics
1761    ///
1762    /// 访问不存在的变量或类型不匹配时会触发Panic
1763    #[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    /// 设置`date`类型全局变量的值,不检查类型
1771    ///
1772    /// # Panics
1773    ///
1774    /// 访问不存在的变量时会触发Panic
1775    ///
1776    /// # Safety
1777    ///
1778    /// 类型不兼容时可能会出现未定义行为
1779    #[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    /// 设置`time`类型全局变量的值
1785    ///
1786    /// # Panics
1787    ///
1788    /// 访问不存在的变量或类型不匹配时会触发Panic
1789    #[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    /// 设置`time`类型全局变量的值,不检查类型
1797    ///
1798    /// # Panics
1799    ///
1800    /// 访问不存在的变量时会触发Panic
1801    ///
1802    /// # Safety
1803    ///
1804    /// 类型不兼容时可能会出现未定义行为
1805    #[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    /// 设置`datetime`类型全局变量的值
1811    ///
1812    /// # Panics
1813    ///
1814    /// 访问不存在的变量或类型不匹配时会触发Panic
1815    #[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    /// 设置`datetime`类型全局变量的值,不检查类型
1823    ///
1824    /// # Panics
1825    ///
1826    /// 访问不存在的变量时会触发Panic
1827    ///
1828    /// # Safety
1829    ///
1830    /// 类型不兼容时可能会出现未定义行为
1831    #[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    /// 设置`char`类型全局变量的值
1841    ///
1842    /// # Panics
1843    ///
1844    /// 访问不存在的变量或类型不匹配时会触发Panic
1845    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    /// 设置`char`类型全局变量的值,不检查类型
1852    ///
1853    /// # Panics
1854    ///
1855    /// 访问不存在的变量时会触发Panic
1856    ///
1857    /// # Safety
1858    ///
1859    /// 类型不兼容时可能会出现未定义行为
1860    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    /// 设置`byte`类型全局变量的值
1865    ///
1866    /// # Panics
1867    ///
1868    /// 访问不存在的变量或类型不匹配时会触发Panic
1869    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    /// 设置`byte`类型全局变量的值,不检查类型
1876    ///
1877    /// # Panics
1878    ///
1879    /// 访问不存在的变量时会触发Panic
1880    ///
1881    /// # Safety
1882    ///
1883    /// 类型不兼容时可能会出现未定义行为
1884    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    /// 设置对象类型全局变量的值
1889    ///
1890    /// # Panics
1891    ///
1892    /// 访问不存在的变量或类型不匹配时会触发Panic
1893    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    /// 设置对象类型全局变量的值,不检查类型
1900    ///
1901    /// # Panics
1902    ///
1903    /// 访问不存在的变量时会触发Panic
1904    ///
1905    /// # Safety
1906    ///
1907    /// 类型不兼容时可能会出现未定义行为
1908    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    /// 设置数组类型全局变量的值
1913    ///
1914    /// # Panics
1915    ///
1916    /// 访问不存在的变量或类型不匹配时会触发Panic
1917    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    /// 设置数组类型全局变量的值,不检查类型
1924    ///
1925    /// # Panics
1926    ///
1927    /// 访问不存在的变量时会触发Panic
1928    ///
1929    /// # Safety
1930    ///
1931    /// 类型不兼容时可能会出现未定义行为
1932    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
1937/*
1938    Method calling
1939*/
1940
1941/// 函数名抽象
1942pub 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/// 全局函数ID
1960#[derive(Clone, Copy)]
1961pub struct GlobalFunctionId {
1962    pub(crate) cls: pbclass,
1963    pub(crate) mid: MethodId
1964}
1965
1966/// 全局函数ID抽象
1967pub 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    /// 获取用户定义全局函数ID
1990    ///
1991    /// # Examples
1992    ///
1993    /// ```
1994    /// let fid = session.get_user_function_id("gf_test").unwrap();
1995    /// let invoker = session.begin_invoke_function(fid).unwrap();
1996    /// invoker.invoke();
1997    /// ```
1998    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    /// 获取系统全局函数ID
2015    ///
2016    /// # Examples
2017    ///
2018    /// ```
2019    /// let fid = session.get_system_function_id(("MessageBox","ISS")).unwrap();
2020    /// let invoker = session.begin_invoke_function(fid).unwrap();
2021    /// invoker.arg(0).set_str("title");
2022    /// invoker.arg(1).set_str("content");
2023    /// invoker.invoke();
2024    /// ```
2025    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    /// 获取任意全局函数ID
2038    ///
2039    /// # Examples
2040    ///
2041    /// ```
2042    /// let fid = session.get_function_id(("MessageBox","ISS")).unwrap();
2043    /// let invoker = session.begin_invoke_function(fid).unwrap();
2044    /// invoker.arg(0).set_str("title");
2045    /// invoker.arg(1).set_str("content");
2046    /// invoker.invoke();
2047    /// ```
2048    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    /// 调用全局函数
2055    ///
2056    /// # Examples
2057    ///
2058    /// ```
2059    /// let rv: pbint = session.invoke_function(("MessageBox","ISS"),pbargs!["title","content"]).unwrap();
2060    /// ```
2061    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    /// 初始化全局函数调用上下文
2073    ///
2074    /// # Examples
2075    ///
2076    /// ```
2077    /// let invoker = session.begin_invoke_function(("MessageBox","ISS")).unwrap();
2078    /// invoker.arg(0).set_str("title");
2079    /// invoker.arg(1).set_str("content");
2080    /// invoker.invoke();
2081    /// ```
2082    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
2149/// 拥有所有权的Session对象
2150///
2151/// 此对象由[`VM`]创建,`drop`时会释放会话
2152pub 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    /// 设置`DebugTrace`文件
2166    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    /// 释放会话
2171    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/// 栈帧
2184///
2185/// 当**直接**从Rust端调用PB代码时一般需要创建栈帧来释放调用阶段产生的临时资源,比如创建的对象
2186///
2187/// # Examples
2188///
2189/// ```
2190/// //创建栈帧
2191/// let frame = LocalFrame::new(&session);
2192/// //手动退出栈帧
2193/// //pop调用不是必须的,变量drop时会自动退出
2194/// frame.pop();
2195/// ```
2196#[must_use]
2197pub struct LocalFrame<'session> {
2198    session: &'session Session
2199}
2200
2201impl<'session> LocalFrame<'session> {
2202    /// 创建栈帧
2203    pub fn new(session: &Session) -> LocalFrame {
2204        unsafe { ffi::pbsession_PushLocalFrame(session.ptr) }
2205        LocalFrame {
2206            session
2207        }
2208    }
2209    /// 手动退出栈帧
2210    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/*
2218thread_local! {
2219    static SESSION: Cell<Option<Session>> = Cell::new(None)
2220}
2221
2222/// 设置线程当前SESSION对象
2223pub(crate) fn set_current_session(session: Session) {
2224    SESSION.with(|s| {
2225        s.set(Some(session));
2226    });
2227}
2228
2229/// 线程当前SESSION对象
2230pub fn current_session() -> Option<Session> { SESSION.with(|s| s.get()) }
2231*/