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
use super::{ProbeArgType, ProbeArgWrapper};

#[cfg(test)]
extern crate quickcheck;

// Using the macro to avoid duplication, implement ProbeArgType and ProbeArgWrapper for the
// intrinsic integer types, with a few non-obvious translations based on C variadic idiosyncracies
macro_rules! impl_integer_arg_type {
    ( $rust_type:ty, $c_type:ty, $tests:ident ) => {
        impl ProbeArgType<$rust_type> for $rust_type {
            type WrapperType = $rust_type;

            fn wrap(arg: $rust_type) -> Self::WrapperType {
                arg
            }
        }

        impl ProbeArgWrapper for $rust_type {
            type CType = $c_type;

            fn as_c_type(&self) -> Self::CType {
                //*self as $c_type
                <$c_type>::from(*self)
            }
        }

        #[cfg(test)]
        mod $tests {
            use crate::{wrap, ProbeArgWrapper};
            use std::mem::size_of;

            #[quickcheck]
            fn converts_to_c_type(x: $rust_type) {
                let wrapper = wrap(x);

                assert_eq!(size_of::<$rust_type>(), size_of::<$c_type>());
                assert_eq!(<$c_type>::from(x), wrapper.as_c_type());
            }
        }
    };
}

impl_integer_arg_type!(usize, libc::size_t, usize_test);
impl_integer_arg_type!(isize, libc::ssize_t, isize_test);
impl_integer_arg_type!(u64, std::os::raw::c_ulonglong, u64_test);
impl_integer_arg_type!(i64, std::os::raw::c_longlong, i64_test);
impl_integer_arg_type!(u32, std::os::raw::c_uint, u32_test);
impl_integer_arg_type!(i32, std::os::raw::c_int, i32_test);
impl_integer_arg_type!(u16, std::os::raw::c_ushort, u16_test);
impl_integer_arg_type!(i16, std::os::raw::c_short, i16_test);
impl_integer_arg_type!(u8, std::os::raw::c_uchar, u8_test);
impl_integer_arg_type!(i8, std::os::raw::c_char, i8_test);