1 pub use std::ptr;
2 
3 macro_rules! merge {
4     ($default:expr => $($field:ident : $value:expr),*) => {
5         {
6             let mut x = $default;
7             $( x.$field = $value; )*
8 
9             x
10         }
11     }
12 }
13 
14 #[macro_export]
15 macro_rules! endpoint_descriptor {
16     ($($key:ident : $value:expr),*) => {
17         merge!(
18             libusb1_sys::libusb_endpoint_descriptor {
19                 bLength:          7,
20                 bDescriptorType:  0x05,
21                 bEndpointAddress: 0x00,
22                 bmAttributes:     0x00,
23                 wMaxPacketSize:   16,
24                 bInterval:        1,
25                 bRefresh:         1,
26                 bSynchAddress:    0,
27                 extra:            $crate::test_helpers::ptr::null(),
28                 extra_length:     0
29             } => $($key: $value),*
30         )
31     }
32 }
33 
34 #[macro_export]
35 macro_rules! interface_descriptor {
36     ($($key:ident : $value:expr),*) => {
37         merge!(
38             libusb1_sys::libusb_interface_descriptor {
39                 bLength:            9,
40                 bDescriptorType:    0x04,
41                 bInterfaceNumber:   0,
42                 bAlternateSetting:  0,
43                 bNumEndpoints:      0,
44                 bInterfaceClass:    0,
45                 bInterfaceSubClass: 0,
46                 bInterfaceProtocol: 0,
47                 iInterface:         0,
48                 endpoint:           $crate::test_helpers::ptr::null(),
49                 extra:              $crate::test_helpers::ptr::null(),
50                 extra_length:       0
51             } => $($key: $value),*
52         )
53     };
54     ($($endpoint:expr),+) => {
55         {
56             let endpoints = vec![$($endpoint),+];
57 
58             let r = libusb1_sys::libusb_interface_descriptor {
59                 bLength:            9,
60                 bDescriptorType:    0x04,
61                 bInterfaceNumber:   0,
62                 bAlternateSetting:  0,
63                 bNumEndpoints:      endpoints.len() as u8,
64                 bInterfaceClass:    0,
65                 bInterfaceSubClass: 0,
66                 bInterfaceProtocol: 0,
67                 iInterface:         0,
68                 endpoint:           (&endpoints[..]).as_ptr(),
69                 extra:              $crate::test_helpers::ptr::null(),
70                 extra_length:       0
71             };
72 
73             // leak the Vec so the returned pointer remains valid
74             ::std::mem::forget(endpoints);
75             r
76         }
77     }
78 }
79 
80 #[macro_export]
81 macro_rules! interface {
82     ($($descriptor:expr),*) => {
83         {
84             let descriptors = vec![$($descriptor),*];
85 
86             let r = libusb1_sys::libusb_interface {
87                 altsetting:     descriptors.as_ptr(),
88                 num_altsetting: descriptors.len() as ::libc::c_int
89             };
90 
91             // leak the Vec so the returned pointer remains valid
92             ::std::mem::forget(descriptors);
93             r
94         }
95     }
96 }
97 
98 #[macro_export]
99 macro_rules! config_descriptor {
100     ($($key:ident : $value:expr),*) => {
101         merge!(
102             libusb1_sys::libusb_config_descriptor {
103                 bLength:             9,
104                 bDescriptorType:     0x02,
105                 wTotalLength:        9,
106                 bNumInterfaces:      0,
107                 bConfigurationValue: 0,
108                 iConfiguration:      0,
109                 bmAttributes:        0x00,
110                 bMaxPower:           10,
111                 interface:           $crate::test_helpers::ptr::null(),
112                 extra:               $crate::test_helpers::ptr::null(),
113                 extra_length:        0
114             } => $($key: $value),*
115         )
116     };
117     ($($interface:expr),+) => {
118         {
119             let interfaces = vec![$($interface),+];
120 
121             let r = libusb1_sys::libusb_config_descriptor {
122                 bLength:             9,
123                 bDescriptorType:     0x02,
124                 wTotalLength:        9,
125                 bNumInterfaces:      interfaces.len() as u8,
126                 bConfigurationValue: 0,
127                 iConfiguration:      0,
128                 bmAttributes:        0x00,
129                 bMaxPower:           10,
130                 interface:           (&interfaces[..]).as_ptr(),
131                 extra:               $crate::test_helpers::ptr::null(),
132                 extra_length:        0
133             };
134 
135             // leak the Vec so the returned pointer remains valid
136             ::std::mem::forget(interfaces);
137             r
138         }
139     }
140 }
141 
142 #[macro_export]
143 macro_rules! device_descriptor {
144     ($($key:ident : $value:expr),*) => {
145         merge!(
146             libusb1_sys::libusb_device_descriptor {
147                 bLength:            18,
148                 bDescriptorType:    0x01,
149                 bcdUSB:             0x0110,
150                 bDeviceClass:       0,
151                 bDeviceSubClass:    0,
152                 bDeviceProtocol:    0,
153                 bMaxPacketSize0:    16,
154                 idVendor:           0x1234,
155                 idProduct:          0x5678,
156                 bcdDevice:          0x0123,
157                 iManufacturer:      0,
158                 iProduct:           0,
159                 iSerialNumber:      0,
160                 bNumConfigurations: 1
161             } => $($key: $value),*
162         )
163     }
164 }
165