1#[cfg(feature = "futures")]
6use futures::future;
7use gio_sys;
8use glib;
9use glib::object::Cast;
10use glib::object::IsA;
11use glib::signal::connect_raw;
12use glib::signal::SignalHandlerId;
13use glib::translate::*;
14use glib::GString;
15use glib_sys;
16use gobject_sys;
17use std::boxed::Box as Box_;
18use std::fmt;
19use std::mem::transmute;
20use std::ptr;
21use Cancellable;
22use Error;
23use InetAddress;
24use ResolverRecordType;
25use SrvTarget;
26
27glib_wrapper! {
28 pub struct Resolver(Object<gio_sys::GResolver, gio_sys::GResolverClass, ResolverClass>);
29
30 match fn {
31 get_type => || gio_sys::g_resolver_get_type(),
32 }
33}
34
35impl Resolver {
36 pub fn get_default() -> Option<Resolver> {
45 unsafe { from_glib_full(gio_sys::g_resolver_get_default()) }
46 }
47}
48
49pub const NONE_RESOLVER: Option<&Resolver> = None;
50
51pub trait ResolverExt: 'static {
52 fn lookup_by_address<P: IsA<InetAddress>, Q: IsA<Cancellable>>(
53 &self,
54 address: &P,
55 cancellable: Option<&Q>,
56 ) -> Result<GString, Error>;
57
58 fn lookup_by_address_async<
59 P: IsA<InetAddress>,
60 Q: IsA<Cancellable>,
61 R: FnOnce(Result<GString, Error>) + Send + 'static,
62 >(
63 &self,
64 address: &P,
65 cancellable: Option<&Q>,
66 callback: R,
67 );
68
69 #[cfg(feature = "futures")]
70 fn lookup_by_address_async_future<P: IsA<InetAddress> + Clone + 'static>(
71 &self,
72 address: &P,
73 ) -> Box_<dyn future::Future<Output = Result<GString, Error>> + std::marker::Unpin>;
74
75 fn lookup_by_name<P: IsA<Cancellable>>(
76 &self,
77 hostname: &str,
78 cancellable: Option<&P>,
79 ) -> Result<Vec<InetAddress>, Error>;
80
81 fn lookup_by_name_async<
82 P: IsA<Cancellable>,
83 Q: FnOnce(Result<Vec<InetAddress>, Error>) + Send + 'static,
84 >(
85 &self,
86 hostname: &str,
87 cancellable: Option<&P>,
88 callback: Q,
89 );
90
91 #[cfg(feature = "futures")]
92 fn lookup_by_name_async_future(
93 &self,
94 hostname: &str,
95 ) -> Box_<dyn future::Future<Output = Result<Vec<InetAddress>, Error>> + std::marker::Unpin>;
96
97 fn lookup_records<P: IsA<Cancellable>>(
98 &self,
99 rrname: &str,
100 record_type: ResolverRecordType,
101 cancellable: Option<&P>,
102 ) -> Result<Vec<glib::Variant>, Error>;
103
104 fn lookup_records_async<
105 P: IsA<Cancellable>,
106 Q: FnOnce(Result<Vec<glib::Variant>, Error>) + Send + 'static,
107 >(
108 &self,
109 rrname: &str,
110 record_type: ResolverRecordType,
111 cancellable: Option<&P>,
112 callback: Q,
113 );
114
115 #[cfg(feature = "futures")]
116 fn lookup_records_async_future(
117 &self,
118 rrname: &str,
119 record_type: ResolverRecordType,
120 ) -> Box_<dyn future::Future<Output = Result<Vec<glib::Variant>, Error>> + std::marker::Unpin>;
121
122 fn lookup_service<P: IsA<Cancellable>>(
123 &self,
124 service: &str,
125 protocol: &str,
126 domain: &str,
127 cancellable: Option<&P>,
128 ) -> Result<Vec<SrvTarget>, Error>;
129
130 fn lookup_service_async<
131 P: IsA<Cancellable>,
132 Q: FnOnce(Result<Vec<SrvTarget>, Error>) + Send + 'static,
133 >(
134 &self,
135 service: &str,
136 protocol: &str,
137 domain: &str,
138 cancellable: Option<&P>,
139 callback: Q,
140 );
141
142 #[cfg(feature = "futures")]
143 fn lookup_service_async_future(
144 &self,
145 service: &str,
146 protocol: &str,
147 domain: &str,
148 ) -> Box_<dyn future::Future<Output = Result<Vec<SrvTarget>, Error>> + std::marker::Unpin>;
149
150 fn set_default(&self);
151
152 fn connect_reload<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
153}
154
155impl<O: IsA<Resolver>> ResolverExt for O {
156 fn lookup_by_address<P: IsA<InetAddress>, Q: IsA<Cancellable>>(
157 &self,
158 address: &P,
159 cancellable: Option<&Q>,
160 ) -> Result<GString, Error> {
161 unsafe {
162 let mut error = ptr::null_mut();
163 let ret = gio_sys::g_resolver_lookup_by_address(
164 self.as_ref().to_glib_none().0,
165 address.as_ref().to_glib_none().0,
166 cancellable.map(|p| p.as_ref()).to_glib_none().0,
167 &mut error,
168 );
169 if error.is_null() {
170 Ok(from_glib_full(ret))
171 } else {
172 Err(from_glib_full(error))
173 }
174 }
175 }
176
177 fn lookup_by_address_async<
178 P: IsA<InetAddress>,
179 Q: IsA<Cancellable>,
180 R: FnOnce(Result<GString, Error>) + Send + 'static,
181 >(
182 &self,
183 address: &P,
184 cancellable: Option<&Q>,
185 callback: R,
186 ) {
187 let user_data: Box<R> = Box::new(callback);
188 unsafe extern "C" fn lookup_by_address_async_trampoline<
189 R: FnOnce(Result<GString, Error>) + Send + 'static,
190 >(
191 _source_object: *mut gobject_sys::GObject,
192 res: *mut gio_sys::GAsyncResult,
193 user_data: glib_sys::gpointer,
194 ) {
195 let mut error = ptr::null_mut();
196 let ret = gio_sys::g_resolver_lookup_by_address_finish(
197 _source_object as *mut _,
198 res,
199 &mut error,
200 );
201 let result = if error.is_null() {
202 Ok(from_glib_full(ret))
203 } else {
204 Err(from_glib_full(error))
205 };
206 let callback: Box<R> = Box::from_raw(user_data as *mut _);
207 callback(result);
208 }
209 let callback = lookup_by_address_async_trampoline::<R>;
210 unsafe {
211 gio_sys::g_resolver_lookup_by_address_async(
212 self.as_ref().to_glib_none().0,
213 address.as_ref().to_glib_none().0,
214 cancellable.map(|p| p.as_ref()).to_glib_none().0,
215 Some(callback),
216 Box::into_raw(user_data) as *mut _,
217 );
218 }
219 }
220
221 #[cfg(feature = "futures")]
222 fn lookup_by_address_async_future<P: IsA<InetAddress> + Clone + 'static>(
223 &self,
224 address: &P,
225 ) -> Box_<dyn future::Future<Output = Result<GString, Error>> + std::marker::Unpin> {
226 use fragile::Fragile;
227 use GioFuture;
228
229 let address = address.clone();
230 GioFuture::new(self, move |obj, send| {
231 let cancellable = Cancellable::new();
232 let send = Fragile::new(send);
233 obj.lookup_by_address_async(&address, Some(&cancellable), move |res| {
234 let _ = send.into_inner().send(res);
235 });
236
237 cancellable
238 })
239 }
240
241 fn lookup_by_name<P: IsA<Cancellable>>(
242 &self,
243 hostname: &str,
244 cancellable: Option<&P>,
245 ) -> Result<Vec<InetAddress>, Error> {
246 unsafe {
247 let mut error = ptr::null_mut();
248 let ret = gio_sys::g_resolver_lookup_by_name(
249 self.as_ref().to_glib_none().0,
250 hostname.to_glib_none().0,
251 cancellable.map(|p| p.as_ref()).to_glib_none().0,
252 &mut error,
253 );
254 if error.is_null() {
255 Ok(FromGlibPtrContainer::from_glib_full(ret))
256 } else {
257 Err(from_glib_full(error))
258 }
259 }
260 }
261
262 fn lookup_by_name_async<
263 P: IsA<Cancellable>,
264 Q: FnOnce(Result<Vec<InetAddress>, Error>) + Send + 'static,
265 >(
266 &self,
267 hostname: &str,
268 cancellable: Option<&P>,
269 callback: Q,
270 ) {
271 let user_data: Box<Q> = Box::new(callback);
272 unsafe extern "C" fn lookup_by_name_async_trampoline<
273 Q: FnOnce(Result<Vec<InetAddress>, Error>) + Send + 'static,
274 >(
275 _source_object: *mut gobject_sys::GObject,
276 res: *mut gio_sys::GAsyncResult,
277 user_data: glib_sys::gpointer,
278 ) {
279 let mut error = ptr::null_mut();
280 let ret = gio_sys::g_resolver_lookup_by_name_finish(
281 _source_object as *mut _,
282 res,
283 &mut error,
284 );
285 let result = if error.is_null() {
286 Ok(FromGlibPtrContainer::from_glib_full(ret))
287 } else {
288 Err(from_glib_full(error))
289 };
290 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
291 callback(result);
292 }
293 let callback = lookup_by_name_async_trampoline::<Q>;
294 unsafe {
295 gio_sys::g_resolver_lookup_by_name_async(
296 self.as_ref().to_glib_none().0,
297 hostname.to_glib_none().0,
298 cancellable.map(|p| p.as_ref()).to_glib_none().0,
299 Some(callback),
300 Box::into_raw(user_data) as *mut _,
301 );
302 }
303 }
304
305 #[cfg(feature = "futures")]
306 fn lookup_by_name_async_future(
307 &self,
308 hostname: &str,
309 ) -> Box_<dyn future::Future<Output = Result<Vec<InetAddress>, Error>> + std::marker::Unpin>
310 {
311 use fragile::Fragile;
312 use GioFuture;
313
314 let hostname = String::from(hostname);
315 GioFuture::new(self, move |obj, send| {
316 let cancellable = Cancellable::new();
317 let send = Fragile::new(send);
318 obj.lookup_by_name_async(&hostname, Some(&cancellable), move |res| {
319 let _ = send.into_inner().send(res);
320 });
321
322 cancellable
323 })
324 }
325
326 fn lookup_records<P: IsA<Cancellable>>(
327 &self,
328 rrname: &str,
329 record_type: ResolverRecordType,
330 cancellable: Option<&P>,
331 ) -> Result<Vec<glib::Variant>, Error> {
332 unsafe {
333 let mut error = ptr::null_mut();
334 let ret = gio_sys::g_resolver_lookup_records(
335 self.as_ref().to_glib_none().0,
336 rrname.to_glib_none().0,
337 record_type.to_glib(),
338 cancellable.map(|p| p.as_ref()).to_glib_none().0,
339 &mut error,
340 );
341 if error.is_null() {
342 Ok(FromGlibPtrContainer::from_glib_full(ret))
343 } else {
344 Err(from_glib_full(error))
345 }
346 }
347 }
348
349 fn lookup_records_async<
350 P: IsA<Cancellable>,
351 Q: FnOnce(Result<Vec<glib::Variant>, Error>) + Send + 'static,
352 >(
353 &self,
354 rrname: &str,
355 record_type: ResolverRecordType,
356 cancellable: Option<&P>,
357 callback: Q,
358 ) {
359 let user_data: Box<Q> = Box::new(callback);
360 unsafe extern "C" fn lookup_records_async_trampoline<
361 Q: FnOnce(Result<Vec<glib::Variant>, Error>) + Send + 'static,
362 >(
363 _source_object: *mut gobject_sys::GObject,
364 res: *mut gio_sys::GAsyncResult,
365 user_data: glib_sys::gpointer,
366 ) {
367 let mut error = ptr::null_mut();
368 let ret = gio_sys::g_resolver_lookup_records_finish(
369 _source_object as *mut _,
370 res,
371 &mut error,
372 );
373 let result = if error.is_null() {
374 Ok(FromGlibPtrContainer::from_glib_full(ret))
375 } else {
376 Err(from_glib_full(error))
377 };
378 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
379 callback(result);
380 }
381 let callback = lookup_records_async_trampoline::<Q>;
382 unsafe {
383 gio_sys::g_resolver_lookup_records_async(
384 self.as_ref().to_glib_none().0,
385 rrname.to_glib_none().0,
386 record_type.to_glib(),
387 cancellable.map(|p| p.as_ref()).to_glib_none().0,
388 Some(callback),
389 Box::into_raw(user_data) as *mut _,
390 );
391 }
392 }
393
394 #[cfg(feature = "futures")]
395 fn lookup_records_async_future(
396 &self,
397 rrname: &str,
398 record_type: ResolverRecordType,
399 ) -> Box_<dyn future::Future<Output = Result<Vec<glib::Variant>, Error>> + std::marker::Unpin>
400 {
401 use fragile::Fragile;
402 use GioFuture;
403
404 let rrname = String::from(rrname);
405 GioFuture::new(self, move |obj, send| {
406 let cancellable = Cancellable::new();
407 let send = Fragile::new(send);
408 obj.lookup_records_async(&rrname, record_type, Some(&cancellable), move |res| {
409 let _ = send.into_inner().send(res);
410 });
411
412 cancellable
413 })
414 }
415
416 fn lookup_service<P: IsA<Cancellable>>(
417 &self,
418 service: &str,
419 protocol: &str,
420 domain: &str,
421 cancellable: Option<&P>,
422 ) -> Result<Vec<SrvTarget>, Error> {
423 unsafe {
424 let mut error = ptr::null_mut();
425 let ret = gio_sys::g_resolver_lookup_service(
426 self.as_ref().to_glib_none().0,
427 service.to_glib_none().0,
428 protocol.to_glib_none().0,
429 domain.to_glib_none().0,
430 cancellable.map(|p| p.as_ref()).to_glib_none().0,
431 &mut error,
432 );
433 if error.is_null() {
434 Ok(FromGlibPtrContainer::from_glib_full(ret))
435 } else {
436 Err(from_glib_full(error))
437 }
438 }
439 }
440
441 fn lookup_service_async<
442 P: IsA<Cancellable>,
443 Q: FnOnce(Result<Vec<SrvTarget>, Error>) + Send + 'static,
444 >(
445 &self,
446 service: &str,
447 protocol: &str,
448 domain: &str,
449 cancellable: Option<&P>,
450 callback: Q,
451 ) {
452 let user_data: Box<Q> = Box::new(callback);
453 unsafe extern "C" fn lookup_service_async_trampoline<
454 Q: FnOnce(Result<Vec<SrvTarget>, Error>) + Send + 'static,
455 >(
456 _source_object: *mut gobject_sys::GObject,
457 res: *mut gio_sys::GAsyncResult,
458 user_data: glib_sys::gpointer,
459 ) {
460 let mut error = ptr::null_mut();
461 let ret = gio_sys::g_resolver_lookup_service_finish(
462 _source_object as *mut _,
463 res,
464 &mut error,
465 );
466 let result = if error.is_null() {
467 Ok(FromGlibPtrContainer::from_glib_full(ret))
468 } else {
469 Err(from_glib_full(error))
470 };
471 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
472 callback(result);
473 }
474 let callback = lookup_service_async_trampoline::<Q>;
475 unsafe {
476 gio_sys::g_resolver_lookup_service_async(
477 self.as_ref().to_glib_none().0,
478 service.to_glib_none().0,
479 protocol.to_glib_none().0,
480 domain.to_glib_none().0,
481 cancellable.map(|p| p.as_ref()).to_glib_none().0,
482 Some(callback),
483 Box::into_raw(user_data) as *mut _,
484 );
485 }
486 }
487
488 #[cfg(feature = "futures")]
489 fn lookup_service_async_future(
490 &self,
491 service: &str,
492 protocol: &str,
493 domain: &str,
494 ) -> Box_<dyn future::Future<Output = Result<Vec<SrvTarget>, Error>> + std::marker::Unpin> {
495 use fragile::Fragile;
496 use GioFuture;
497
498 let service = String::from(service);
499 let protocol = String::from(protocol);
500 let domain = String::from(domain);
501 GioFuture::new(self, move |obj, send| {
502 let cancellable = Cancellable::new();
503 let send = Fragile::new(send);
504 obj.lookup_service_async(
505 &service,
506 &protocol,
507 &domain,
508 Some(&cancellable),
509 move |res| {
510 let _ = send.into_inner().send(res);
511 },
512 );
513
514 cancellable
515 })
516 }
517
518 fn set_default(&self) {
519 unsafe {
520 gio_sys::g_resolver_set_default(self.as_ref().to_glib_none().0);
521 }
522 }
523
524 fn connect_reload<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
525 unsafe extern "C" fn reload_trampoline<P, F: Fn(&P) + 'static>(
526 this: *mut gio_sys::GResolver,
527 f: glib_sys::gpointer,
528 ) where
529 P: IsA<Resolver>,
530 {
531 let f: &F = &*(f as *const F);
532 f(&Resolver::from_glib_borrow(this).unsafe_cast())
533 }
534 unsafe {
535 let f: Box_<F> = Box_::new(f);
536 connect_raw(
537 self.as_ptr() as *mut _,
538 b"reload\0".as_ptr() as *const _,
539 Some(transmute(reload_trampoline::<Self, F> as usize)),
540 Box_::into_raw(f),
541 )
542 }
543 }
544}
545
546impl fmt::Display for Resolver {
547 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
548 write!(f, "Resolver")
549 }
550}