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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
#![allow(let_and_return)]
extern crate dbus;
#[macro_export]
macro_rules! dbus_functions {
($factory:expr, $interface:ident,) => {
};
($factory:expr, $interface:ident, fn $func_name:ident () -> $return_type:ty $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let result = $block;
Ok(vec!(method.msg.method_return().append1(result)))
})
.outarg::<$return_type, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident () $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
$block;
let result = 0;
Ok(vec!(method.msg.method_return().append1(result)))
})
.outarg::<i32, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty ) -> $return_type:ty $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let $arg1: $arg1_type = method.msg.get1().unwrap();
let result = $block;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.outarg::<$return_type, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty ) $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let $arg1: $arg1_type = method.msg.get1().unwrap();
$block;
let result = 0;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.outarg::<i32, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty ) -> $return_type:ty $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2): (Option<$arg1_type>, Option<$arg2_type>) = method.msg.get2();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let result = $block;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.outarg::<$return_type, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty ) $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2): (Option<$arg1_type>, Option<$arg2_type>) = method.msg.get2();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
$block;
let result = 0;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.outarg::<i32, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty) -> $return_type:ty $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2, $arg3): (Option<$arg1_type>, Option<$arg2_type>, Option<$arg3_type>) = method.msg.get3();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let $arg3 = $arg3.unwrap();
let result = $block;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.inarg::<$arg3_type, _>(stringify!($arg3))
.outarg::<$return_type, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty) $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2, $arg3): (Option<$arg1_type>, Option<$arg2_type>, Option<$arg3_type>) = method.msg.get3();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let $arg3 = $arg3.unwrap();
$block;
let result = 0;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.inarg::<$arg3_type, _>(stringify!($arg3))
.outarg::<i32, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty) -> $return_type:ty $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2, $arg3, $arg4): (Option<$arg1_type>, Option<$arg2_type>, Option<$arg3_type>, Option<$arg4_type>) = method.msg.get4();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let $arg3 = $arg3.unwrap();
let $arg4 = $arg4.unwrap();
let result = $block;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.inarg::<$arg3_type, _>(stringify!($arg3))
.inarg::<$arg4_type, _>(stringify!($arg4))
.outarg::<$return_type, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty) $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2, $arg3, $arg4): (Option<$arg1_type>, Option<$arg2_type>, Option<$arg3_type>, Option<$arg4_type>) = method.msg.get4();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let $arg3 = $arg3.unwrap();
let $arg4 = $arg4.unwrap();
$block;
let result = 0;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.inarg::<$arg3_type, _>(stringify!($arg3))
.inarg::<$arg4_type, _>(stringify!($arg4))
.outarg::<i32, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty, $arg5:ident : $arg5_type:ty) -> $return_type:ty $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2, $arg3, $arg4, $arg5): (Option<$arg1_type>, Option<$arg2_type>, Option<$arg3_type>, Option<$arg4_type>, Option<$arg5_type>) = method.msg.get5();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let $arg3 = $arg3.unwrap();
let $arg4 = $arg4.unwrap();
let $arg5 = $arg5.unwrap();
let result = $block;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.inarg::<$arg3_type, _>(stringify!($arg3))
.inarg::<$arg4_type, _>(stringify!($arg4))
.inarg::<$arg5_type, _>(stringify!($arg5))
.outarg::<$return_type, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
($factory:expr, $interface:ident, fn $func_name:ident ( $arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty, $arg5:ident : $arg5_type:ty) $block:block $($rest:tt)*) => {
let $interface = $interface.add_m(
$factory.method(stringify!($func_name), (), move |method| {
let ($arg1, $arg2, $arg3, $arg4, $arg5): (Option<$arg1_type>, Option<$arg2_type>, Option<$arg3_type>, Option<$arg4_type>, Option<$arg5_type>) = method.msg.get5();
let $arg1 = $arg1.unwrap();
let $arg2 = $arg2.unwrap();
let $arg3 = $arg3.unwrap();
let $arg4 = $arg4.unwrap();
let $arg5 = $arg5.unwrap();
$block;
let result = 0;
Ok(vec!(method.msg.method_return().append1(result)))
})
.inarg::<$arg1_type, _>(stringify!($arg1))
.inarg::<$arg2_type, _>(stringify!($arg2))
.inarg::<$arg3_type, _>(stringify!($arg3))
.inarg::<$arg4_type, _>(stringify!($arg4))
.inarg::<$arg5_type, _>(stringify!($arg5))
.outarg::<i32, _>("result")
);
dbus_functions!($factory, $interface, $($rest)*);
};
}
#[macro_export]
macro_rules! dbus_class {
($bus_name:expr, $interface_name:expr, class $class_name:ident { $($functions:tt)* }) => {{
extern crate dbus;
let connection = dbus::Connection::get_private(dbus::BusType::Session).unwrap();
connection.register_name($bus_name, dbus::NameFlag::ReplaceExisting as u32).unwrap();
let factory = dbus::tree::Factory::new_fn::<()>();
let class = factory.tree().add(factory.object_path(format!("/{}", stringify!($class_name)), ()).introspectable().add({
let interface = factory.interface($interface_name, ());
dbus_functions!(factory, interface, $($functions)*);
interface
}));
class.set_registered(&connection, true).unwrap();
move || {
for _ in class.run(&connection, connection.iter(1000)) {
}
}
}};
}
#[macro_export]
macro_rules! dbus_prototypes {
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, ) => {
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident () -> $return_type:ty; $($rest:tt)*) => {
let $func_name = || -> $return_type {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let response = $connection.send_with_reply_and_block(message, 2000).unwrap();
response.get1().unwrap()
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident (); $($rest:tt)*) => {
let $func_name = || {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
$connection.send_with_reply_and_block(message, 2000).unwrap();
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty) -> $return_type:ty; $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type| -> $return_type {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append1($arg1);
let response = $connection.send_with_reply_and_block(message, 2000).unwrap();
response.get1().unwrap()
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty) ; $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type| {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append1($arg1);
$connection.send_with_reply_and_block(message, 2000).unwrap();
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty) -> $return_type:ty; $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type| -> $return_type {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append2($arg1, $arg2);
let response = $connection.send_with_reply_and_block(message, 2000).unwrap();
response.get1().unwrap()
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty); $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type| {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append2($arg1, $arg2);
$connection.send_with_reply_and_block(message, 2000).unwrap();
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty) -> $return_type:ty; $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type, $arg3: $arg3_type| -> $return_type {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append3($arg1, $arg2, $arg3);
let response = $connection.send_with_reply_and_block(message, 2000).unwrap();
response.get1().unwrap()
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty); $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type, $arg3: $arg3_type| {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append3($arg1, $arg2, $arg3);
$connection.send_with_reply_and_block(message, 2000).unwrap();
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty) -> $return_type:ty; $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type, $arg3: $arg3_type, $arg4: $arg4_type| -> $return_type {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append($arg1);
let message = message.append($arg2);
let message = message.append($arg3);
let message = message.append($arg4);
let response = $connection.send_with_reply_and_block(message, 2000).unwrap();
response.get1().unwrap()
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty); $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type, $arg3: $arg3_type, $arg4: $arg4_type| {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append($arg1);
let message = message.append($arg2);
let message = message.append($arg3);
let message = message.append($arg4);
$connection.send_with_reply_and_block(message, 2000).unwrap();
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty, $arg5:ident : $arg5_type:ty) -> $return_type:ty; $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type, $arg3: $arg3_type, $arg4: $arg4_type, $arg5: $arg5_type| -> $return_type {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append($arg1);
let message = message.append($arg2);
let message = message.append($arg3);
let message = message.append($arg4);
let message = message.append($arg5);
let response = $connection.send_with_reply_and_block(message, 2000).unwrap();
response.get1().unwrap()
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
($connection:expr, $name:expr, $interface_name:expr, $class_name:ident, fn $func_name:ident ($arg1:ident : $arg1_type:ty, $arg2:ident : $arg2_type:ty, $arg3:ident : $arg3_type:ty, $arg4:ident : $arg4_type:ty, $arg5:ident : $arg5_type:ty); $($rest:tt)*) => {
let $func_name = |$arg1: $arg1_type, $arg2: $arg2_type, $arg3: $arg3_type, $arg4: $arg4_type, $arg5: $arg5_type| {
let message = dbus::Message::new_method_call($name, &format!("/{}", stringify!($class_name)), $interface_name, stringify!($func_name)).unwrap();
let message = message.append($arg1);
let message = message.append($arg2);
let message = message.append($arg3);
let message = message.append($arg4);
let message = message.append($arg5);
$connection.send_with_reply_and_block(message, 2000).unwrap();
};
dbus_prototypes!($connection, $name, $interface_name, $class_name, $($rest)*);
};
}
#[macro_export]
macro_rules! dbus_interface {
($name:expr, $interface_name:expr, interface $class_name:ident { $($prototypes:tt)* }) => {
extern crate dbus;
let connection = dbus::Connection::get_private(dbus::BusType::Session).unwrap();
dbus_prototypes!(connection, $name, $interface_name, $class_name, $($prototypes)*)
};
}