1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use super::{ProbeArgNativeType, ProbeArgType, ProbeArgWrapper};
use std::ffi::CString;
use std::fmt::Debug;
use std::marker::Copy;
impl<T> ProbeArgType<&Option<T>> for &Option<T>
where
T: ProbeArgType<T> + Copy,
{
type WrapperType = Option<<T as ProbeArgType<T>>::WrapperType>;
fn wrap(arg: &Option<T>) -> Self::WrapperType {
arg.as_ref().map(super::wrap)
}
}
impl ProbeArgType<&Option<String>> for &Option<String> {
type WrapperType = Option<CString>;
fn wrap(arg: &Option<String>) -> Self::WrapperType {
arg.as_ref().and_then(super::wrap)
}
}
impl<T> ProbeArgWrapper for Option<T>
where
T: ProbeArgWrapper + Debug,
{
type CType = <T as ProbeArgWrapper>::CType;
fn as_c_type(&self) -> Self::CType {
let wrapped = self.as_ref().map(ProbeArgWrapper::as_c_type);
let default: Self::CType =
<Self::CType as ProbeArgNativeType<Self::CType>>::get_default_value();
wrapped.unwrap_or(default)
}
}
#[cfg(test)]
mod tests {
use crate::{wrap, ProbeArgWrapper};
use std::ptr;
#[quickcheck]
fn option_ints(x: i64) -> bool {
let some = Some(x);
let none: Option<i64> = None;
assert_eq!(x, wrap(&some).as_c_type());
assert_eq!(0, wrap(&none).as_c_type());
true
}
#[quickcheck]
fn option_strings(x: String) -> bool {
let some = Some(x.clone());
let none: Option<String> = None;
let naked_wrapper = wrap(&x);
let opt_wrapper = wrap(&some);
assert_eq!(naked_wrapper, opt_wrapper);
assert_eq!(ptr::null(), wrap(&none).as_c_type());
let some = Some(x.as_str());
let none = None;
let naked_wrapper = wrap(x.as_str());
let opt_wrapper = wrap(&some);
assert_eq!(Some(naked_wrapper), opt_wrapper);
assert_eq!(ptr::null(), wrap::<&Option<&str>>(&none).as_c_type());
true
}
}