1use crate::{bindings::*, *};
2use std::ptr;
3
4pub struct Arguments<'args> {
13 ci: pbcallinfo,
14 count: pbint,
15 session: Session,
16 _marker: PhantomData<&'args pbcallinfo>
17}
18
19impl<'args> Arguments<'args> {
20 pub(crate) unsafe fn from_ptr(ci: pbcallinfo, session: Session) -> Arguments<'args> {
21 let count = ffi::pbargs_GetCount(ci.as_ref().pArgs);
22 Arguments {
23 ci,
24 count,
25 session,
26 _marker: PhantomData
27 }
28 }
29
30 pub fn as_ref(&self) -> ArgumentsRef {
32 unsafe { ArgumentsRef::from_ptr(self.ci.as_ref().pArgs, self.session.clone()) }
33 }
34
35 pub fn iter(&self) -> ArgumentsIter {
37 let args = unsafe { ArgumentsRef::from_ptr(self.ci.as_ref().pArgs, self.session.clone()) };
38 ArgumentsIter {
39 args,
40 idx: 0
41 }
42 }
43
44 pub fn count(&self) -> pbint { self.count }
46
47 pub fn get(&self, index: pbint) -> Value<'args> {
53 if let Ok(val) = self.try_get(index) {
54 val
55 } else {
56 panic!("arg index {} is out of bound {}", index, self.count)
57 }
58 }
59
60 pub fn try_get(&self, index: pbint) -> Result<Value<'args>> {
62 if index < 0 || index >= self.count {
63 return Err(PBXRESULT::E_ARRAY_INDEX_OUTOF_BOUNDS);
64 }
65 unsafe { Ok(Value::from_ptr(ffi::pbargs_GetAt(self.ci.as_ref().pArgs, index), self.session.clone())) }
66 }
67
68 pub fn add_int(&mut self, value: impl Into<Option<pbint>>) -> Result<()> {
70 let value = value.into();
71 unsafe {
72 let pbxr = ffi::pbsession_AddIntArgument(
73 self.session.as_ptr(),
74 self.ci,
75 value.unwrap_or_default(),
76 value.is_none().into()
77 );
78 if pbxr.is_ok() {
79 self.count += 1;
80 }
81 pbxr.into()
82 }
83 }
84
85 pub fn add_uint(&mut self, value: impl Into<Option<pbuint>>) -> Result<()> {
87 let value = value.into();
88 unsafe {
89 let pbxr = ffi::pbsession_AddUintArgument(
90 self.session.as_ptr(),
91 self.ci,
92 value.unwrap_or_default(),
93 value.is_none().into()
94 );
95 if pbxr.is_ok() {
96 self.count += 1;
97 }
98 pbxr.into()
99 }
100 }
101
102 pub fn add_long(&mut self, value: impl Into<Option<pblong>>) -> Result<()> {
104 let value = value.into();
105 unsafe {
106 let pbxr = ffi::pbsession_AddLongArgument(
107 self.session.as_ptr(),
108 self.ci,
109 value.unwrap_or_default(),
110 value.is_none().into()
111 );
112 if pbxr.is_ok() {
113 self.count += 1;
114 }
115 pbxr.into()
116 }
117 }
118
119 pub fn add_ulong(&mut self, value: impl Into<Option<pbulong>>) -> Result<()> {
121 let value = value.into();
122 unsafe {
123 let pbxr = ffi::pbsession_AddUlongArgument(
124 self.session.as_ptr(),
125 self.ci,
126 value.unwrap_or_default(),
127 value.is_none().into()
128 );
129 if pbxr.is_ok() {
130 self.count += 1;
131 }
132 pbxr.into()
133 }
134 }
135
136 pub fn add_longlong(&mut self, value: impl Into<Option<pblonglong>>) -> Result<()> {
138 let value = value.into();
139 unsafe {
140 let pbxr = ffi::pbsession_AddLongLongArgument(
141 self.session.as_ptr(),
142 self.ci,
143 value.unwrap_or_default(),
144 value.is_none().into()
145 );
146 if pbxr.is_ok() {
147 self.count += 1;
148 }
149 pbxr.into()
150 }
151 }
152
153 pub fn add_real(&mut self, value: impl Into<Option<pbreal>>) -> Result<()> {
155 let value = value.into();
156 unsafe {
157 let pbxr = ffi::pbsession_AddRealArgument(
158 self.session.as_ptr(),
159 self.ci,
160 value.unwrap_or_default(),
161 value.is_none().into()
162 );
163 if pbxr.is_ok() {
164 self.count += 1;
165 }
166 pbxr.into()
167 }
168 }
169
170 pub fn add_double(&mut self, value: impl Into<Option<pbdouble>>) -> Result<()> {
172 let value = value.into();
173 unsafe {
174 let pbxr = ffi::pbsession_AddDoubleArgument(
175 self.session.as_ptr(),
176 self.ci,
177 value.unwrap_or_default(),
178 value.is_none().into()
179 );
180 if pbxr.is_ok() {
181 self.count += 1;
182 }
183 pbxr.into()
184 }
185 }
186
187 #[cfg(feature = "decimal")]
189 pub fn add_dec(&mut self, value: impl Into<Option<Decimal>>) -> Result<()> {
190 unsafe {
191 let value = value.into().map(|v| self.session.new_pbdec(v));
192 let pbxr = ffi::pbsession_AddDecArgument(
193 self.session.as_ptr(),
194 self.ci,
195 value.unwrap_or(NonNull::new_unchecked(0 as _)),
196 value.is_none().into()
197 );
198 if pbxr.is_ok() {
199 self.count += 1;
200 }
201 pbxr.into()
202 }
203 }
204
205 pub fn add_string<T, D>(&mut self, value: T) -> Result<()>
207 where
208 T: Into<Option<D>>,
209 D: AsPBStr
210 {
211 let value = value.into();
212 unsafe {
213 let value = value.map(|v| v.as_pbstr().as_ptr());
214 let pbxr = ffi::pbsession_AddStringArgument(
215 self.session.as_ptr(),
216 self.ci,
217 value.unwrap_or(ptr::null()),
218 value.is_none().into()
219 );
220 if pbxr.is_ok() {
221 self.count += 1;
222 }
223 pbxr.into()
224 }
225 }
226
227 pub fn add_bool(&mut self, value: impl Into<Option<bool>>) -> Result<()> {
229 let value = value.into();
230 unsafe {
231 let pbxr = ffi::pbsession_AddBoolArgument(
232 self.session.as_ptr(),
233 self.ci,
234 value.unwrap_or_default().into(),
235 value.is_none().into()
236 );
237 if pbxr.is_ok() {
238 self.count += 1;
239 }
240 pbxr.into()
241 }
242 }
243
244 pub fn add_blob<'a>(&mut self, value: impl Into<Option<&'a [u8]>>) -> Result<()> {
246 let value = value.into();
247 if let Some(ref value) = value {
248 if value.is_empty() {
249 return Err(PBXRESULT::E_OUTOF_MEMORY);
250 }
251 }
252 unsafe {
253 let value = value.map(|v| self.session.new_pbblob(v));
254 let pbxr = ffi::pbsession_AddBlobArgument(
255 self.session.as_ptr(),
256 self.ci,
257 value.unwrap_or(NonNull::new_unchecked(0 as _)),
258 value.is_none().into()
259 );
260 if pbxr.is_ok() {
261 self.count += 1;
262 }
263 pbxr.into()
264 }
265 }
266
267 #[cfg(feature = "datetime")]
269 pub fn add_date(&mut self, value: impl Into<Option<NaiveDate>>) -> Result<()> {
270 unsafe {
271 let value = value.into().map(|v| self.session.new_pbdate(v));
272 let pbxr = ffi::pbsession_AddDateArgument(
273 self.session.as_ptr(),
274 self.ci,
275 value.unwrap_or(NonNull::new_unchecked(0 as _)),
276 value.is_none().into()
277 );
278 if pbxr.is_ok() {
279 self.count += 1;
280 }
281 pbxr.into()
282 }
283 }
284
285 #[cfg(feature = "datetime")]
287 pub fn add_time(&mut self, value: impl Into<Option<NaiveTime>>) -> Result<()> {
288 unsafe {
289 let value = value.into().map(|v| self.session.new_pbtime(v));
290 let pbxr = ffi::pbsession_AddTimeArgument(
291 self.session.as_ptr(),
292 self.ci,
293 value.unwrap_or(NonNull::new_unchecked(0 as _)),
294 value.is_none().into()
295 );
296 if pbxr.is_ok() {
297 self.count += 1;
298 }
299 pbxr.into()
300 }
301 }
302
303 #[cfg(feature = "datetime")]
305 pub fn add_datetime(&mut self, value: impl Into<Option<NaiveDateTime>>) -> Result<()> {
306 unsafe {
307 let value = value.into().map(|v| self.session.new_pbdatetime(v));
308 let pbxr = ffi::pbsession_AddDateTimeArgument(
309 self.session.as_ptr(),
310 self.ci,
311 value.unwrap_or(NonNull::new_unchecked(0 as _)),
312 value.is_none().into()
313 );
314 if pbxr.is_ok() {
315 self.count += 1;
316 }
317 pbxr.into()
318 }
319 }
320
321 pub fn add_char(&mut self, value: impl Into<Option<PBChar>>) -> Result<()> {
323 let value = value.into();
324 unsafe {
325 let pbxr = ffi::pbsession_AddCharArgument(
326 self.session.as_ptr(),
327 self.ci,
328 value.unwrap_or_default(),
329 value.is_none().into()
330 );
331 if pbxr.is_ok() {
332 self.count += 1;
333 }
334 pbxr.into()
335 }
336 }
337
338 pub fn add_object<'a, 'b: 'a>(&mut self, value: impl Into<Option<&'a Object<'b>>>) -> Result<()> {
340 unsafe {
341 let value = value.into().map(|v| v.as_ptr());
342 let pbxr = ffi::pbsession_AddObjectArgument(
343 self.session.as_ptr(),
344 self.ci,
345 value.unwrap_or(NonNull::new_unchecked(0 as _)),
346 value.is_none().into()
347 );
348 if pbxr.is_ok() {
349 self.count += 1;
350 }
351 pbxr.into()
352 }
353 }
354
355 pub fn add_array<'a, 'b: 'a>(&mut self, value: impl Into<Option<&'a Array<'b>>>) -> Result<()> {
357 unsafe {
358 let value = value.into().map(|v| v.as_ptr());
359 let pbxr = ffi::pbsession_AddArrayArgument(
360 self.session.as_ptr(),
361 self.ci,
362 value.unwrap_or(NonNull::new_unchecked(0 as _)),
363 value.is_none().into()
364 );
365 if pbxr.is_ok() {
366 self.count += 1;
367 }
368 pbxr.into()
369 }
370 }
371}
372
373pub struct ArgumentsRef<'args> {
375 ptr: pbarguments,
376 count: pbint,
377 session: Session,
378 _marker: PhantomData<&'args pbarguments>
379}
380
381impl<'args> ArgumentsRef<'args> {
382 pub(crate) unsafe fn from_ptr(ptr: pbarguments, session: Session) -> ArgumentsRef<'args> {
383 let count = ffi::pbargs_GetCount(ptr);
384 ArgumentsRef {
385 ptr,
386 count,
387 session,
388 _marker: PhantomData
389 }
390 }
391 pub(crate) fn clone(&self) -> ArgumentsRef<'args> {
392 ArgumentsRef {
393 ptr: self.ptr,
394 count: self.count,
395 session: unsafe { self.session.clone() },
396 _marker: PhantomData
397 }
398 }
399
400 pub fn iter(&self) -> ArgumentsIter {
402 let args = unsafe { ArgumentsRef::from_ptr(self.ptr, self.session.clone()) };
403 ArgumentsIter {
404 args,
405 idx: 0
406 }
407 }
408
409 pub fn count(&self) -> pbint { self.count }
411
412 pub fn get(&self, index: pbint) -> Value<'args> {
418 if let Ok(val) = self.try_get(index) {
419 val
420 } else {
421 panic!("arg index {} is out of bound {}", index, self.count)
422 }
423 }
424
425 pub fn try_get(&self, index: pbint) -> Result<Value<'args>> {
427 if index < 0 || index >= self.count {
428 return Err(PBXRESULT::E_ARRAY_INDEX_OUTOF_BOUNDS);
429 }
430 unsafe { Ok(Value::from_ptr(ffi::pbargs_GetAt(self.ptr, index), self.session.clone())) }
431 }
432}
433
434pub struct ArgumentsIter<'args> {
436 args: ArgumentsRef<'args>,
437 idx: pbint
438}
439
440impl<'args> Iterator for ArgumentsIter<'args> {
441 type Item = Value<'args>;
442 fn next(&mut self) -> Option<Self::Item> {
443 let idx = self.idx;
444 self.idx += 1;
445 if idx < self.args.count() {
446 Some(self.args.get(idx))
447 } else {
448 None
449 }
450 }
451 fn size_hint(&self) -> (usize, Option<usize>) { (0, Some(self.args.count() as usize)) }
452}
453
454impl<'args> IntoIterator for Arguments<'args> {
455 type Item = Value<'args>;
456 type IntoIter = ArgumentsIter<'args>;
457
458 fn into_iter(self) -> Self::IntoIter {
459 let args = unsafe { ArgumentsRef::from_ptr(self.ci.as_ref().pArgs, self.session.clone()) };
460 ArgumentsIter {
461 args,
462 idx: 0
463 }
464 }
465}
466
467impl<'args> IntoIterator for ArgumentsRef<'args> {
468 type Item = Value<'args>;
469 type IntoIter = ArgumentsIter<'args>;
470
471 fn into_iter(self) -> Self::IntoIter {
472 ArgumentsIter {
473 args: self,
474 idx: 0
475 }
476 }
477}