gio/auto/resolver.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5#[cfg(feature = "v2_60")]
6#[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
7use crate::ResolverNameLookupFlags;
8use crate::{ffi, AsyncResult, Cancellable, InetAddress, ResolverRecordType, SrvTarget};
9use glib::{
10 object::ObjectType as _,
11 prelude::*,
12 signal::{connect_raw, SignalHandlerId},
13 translate::*,
14};
15use std::{boxed::Box as Box_, pin::Pin};
16
17glib::wrapper! {
18 /// The object that handles DNS resolution. Use [`default()`][Self::default()]
19 /// to get the default resolver.
20 ///
21 /// `GResolver` provides cancellable synchronous and asynchronous DNS
22 /// resolution, for hostnames ([`ResolverExt::lookup_by_address()`][crate::prelude::ResolverExt::lookup_by_address()],
23 /// [`ResolverExt::lookup_by_name()`][crate::prelude::ResolverExt::lookup_by_name()] and their async variants) and SRV
24 /// (service) records ([`ResolverExt::lookup_service()`][crate::prelude::ResolverExt::lookup_service()]).
25 ///
26 /// [`NetworkAddress`][crate::NetworkAddress] and [`NetworkService`][crate::NetworkService] provide wrappers
27 /// around `GResolver` functionality that also implement
28 /// [`SocketConnectable`][crate::SocketConnectable], making it easy to connect to a remote
29 /// host/service.
30 ///
31 /// The default resolver (see [`default()`][Self::default()]) has a timeout of
32 /// 30s set on it since GLib 2.78. Earlier versions of GLib did not support
33 /// resolver timeouts.
34 ///
35 /// This is an abstract type; subclasses of it implement different resolvers for
36 /// different platforms and situations.
37 ///
38 /// This is an Abstract Base Class, you cannot instantiate it.
39 ///
40 /// ## Properties
41 ///
42 ///
43 /// #### `timeout`
44 /// The timeout applied to all resolver lookups, in milliseconds.
45 ///
46 /// This may be changed through the lifetime of the #GResolver. The new value
47 /// will apply to any lookups started after the change, but not to any
48 /// already-ongoing lookups.
49 ///
50 /// If this is `0`, no timeout is applied to lookups.
51 ///
52 /// No timeout was applied to lookups before this property was added in
53 /// GLib 2.78.
54 ///
55 /// Readable | Writeable
56 ///
57 /// ## Signals
58 ///
59 ///
60 /// #### `reload`
61 /// Emitted when the resolver notices that the system resolver
62 /// configuration has changed.
63 ///
64 ///
65 ///
66 /// # Implements
67 ///
68 /// [`ResolverExt`][trait@crate::prelude::ResolverExt], [`trait@glib::ObjectExt`]
69 #[doc(alias = "GResolver")]
70 pub struct Resolver(Object<ffi::GResolver, ffi::GResolverClass>);
71
72 match fn {
73 type_ => || ffi::g_resolver_get_type(),
74 }
75}
76
77impl Resolver {
78 pub const NONE: Option<&'static Resolver> = None;
79
80 //#[doc(alias = "g_resolver_free_addresses")]
81 //pub fn free_addresses(addresses: /*Unimplemented*/&[&Basic: Pointer]) {
82 // unsafe { TODO: call ffi:g_resolver_free_addresses() }
83 //}
84
85 //#[doc(alias = "g_resolver_free_targets")]
86 //pub fn free_targets(targets: /*Unimplemented*/&[&Basic: Pointer]) {
87 // unsafe { TODO: call ffi:g_resolver_free_targets() }
88 //}
89
90 /// Gets the default #GResolver. You should unref it when you are done
91 /// with it. #GResolver may use its reference count as a hint about how
92 /// many threads it should allocate for concurrent DNS resolutions.
93 ///
94 /// # Returns
95 ///
96 /// the default #GResolver.
97 #[doc(alias = "g_resolver_get_default")]
98 #[doc(alias = "get_default")]
99 #[allow(clippy::should_implement_trait)]
100 pub fn default() -> Resolver {
101 unsafe { from_glib_full(ffi::g_resolver_get_default()) }
102 }
103}
104
105/// Trait containing all [`struct@Resolver`] methods.
106///
107/// # Implementors
108///
109/// [`Resolver`][struct@crate::Resolver]
110pub trait ResolverExt: IsA<Resolver> + 'static {
111 /// Get the timeout applied to all resolver lookups. See #GResolver:timeout.
112 ///
113 /// # Returns
114 ///
115 /// the resolver timeout, in milliseconds, or `0` for no timeout
116 #[cfg(feature = "v2_78")]
117 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
118 #[doc(alias = "g_resolver_get_timeout")]
119 #[doc(alias = "get_timeout")]
120 fn timeout(&self) -> u32 {
121 unsafe { ffi::g_resolver_get_timeout(self.as_ref().to_glib_none().0) }
122 }
123
124 /// Synchronously reverse-resolves @address to determine its
125 /// associated hostname.
126 ///
127 /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
128 /// a value from #GResolverError.
129 ///
130 /// If @cancellable is non-[`None`], it can be used to cancel the
131 /// operation, in which case @error (if non-[`None`]) will be set to
132 /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
133 /// ## `address`
134 /// the address to reverse-resolve
135 /// ## `cancellable`
136 /// a #GCancellable, or [`None`]
137 ///
138 /// # Returns
139 ///
140 /// a hostname (either ASCII-only, or in ASCII-encoded
141 /// form), or [`None`] on error.
142 #[doc(alias = "g_resolver_lookup_by_address")]
143 fn lookup_by_address(
144 &self,
145 address: &impl IsA<InetAddress>,
146 cancellable: Option<&impl IsA<Cancellable>>,
147 ) -> Result<glib::GString, glib::Error> {
148 unsafe {
149 let mut error = std::ptr::null_mut();
150 let ret = ffi::g_resolver_lookup_by_address(
151 self.as_ref().to_glib_none().0,
152 address.as_ref().to_glib_none().0,
153 cancellable.map(|p| p.as_ref()).to_glib_none().0,
154 &mut error,
155 );
156 if error.is_null() {
157 Ok(from_glib_full(ret))
158 } else {
159 Err(from_glib_full(error))
160 }
161 }
162 }
163
164 /// Begins asynchronously reverse-resolving @address to determine its
165 /// associated hostname, and eventually calls @callback, which must
166 /// call g_resolver_lookup_by_address_finish() to get the final result.
167 /// ## `address`
168 /// the address to reverse-resolve
169 /// ## `cancellable`
170 /// a #GCancellable, or [`None`]
171 /// ## `callback`
172 /// callback to call after resolution completes
173 #[doc(alias = "g_resolver_lookup_by_address_async")]
174 fn lookup_by_address_async<P: FnOnce(Result<glib::GString, glib::Error>) + 'static>(
175 &self,
176 address: &impl IsA<InetAddress>,
177 cancellable: Option<&impl IsA<Cancellable>>,
178 callback: P,
179 ) {
180 let main_context = glib::MainContext::ref_thread_default();
181 let is_main_context_owner = main_context.is_owner();
182 let has_acquired_main_context = (!is_main_context_owner)
183 .then(|| main_context.acquire().ok())
184 .flatten();
185 assert!(
186 is_main_context_owner || has_acquired_main_context.is_some(),
187 "Async operations only allowed if the thread is owning the MainContext"
188 );
189
190 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
191 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
192 unsafe extern "C" fn lookup_by_address_async_trampoline<
193 P: FnOnce(Result<glib::GString, glib::Error>) + 'static,
194 >(
195 _source_object: *mut glib::gobject_ffi::GObject,
196 res: *mut crate::ffi::GAsyncResult,
197 user_data: glib::ffi::gpointer,
198 ) {
199 let mut error = std::ptr::null_mut();
200 let ret =
201 ffi::g_resolver_lookup_by_address_finish(_source_object as *mut _, res, &mut error);
202 let result = if error.is_null() {
203 Ok(from_glib_full(ret))
204 } else {
205 Err(from_glib_full(error))
206 };
207 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
208 Box_::from_raw(user_data as *mut _);
209 let callback: P = callback.into_inner();
210 callback(result);
211 }
212 let callback = lookup_by_address_async_trampoline::<P>;
213 unsafe {
214 ffi::g_resolver_lookup_by_address_async(
215 self.as_ref().to_glib_none().0,
216 address.as_ref().to_glib_none().0,
217 cancellable.map(|p| p.as_ref()).to_glib_none().0,
218 Some(callback),
219 Box_::into_raw(user_data) as *mut _,
220 );
221 }
222 }
223
224 fn lookup_by_address_future(
225 &self,
226 address: &(impl IsA<InetAddress> + Clone + 'static),
227 ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::GString, glib::Error>> + 'static>>
228 {
229 let address = address.clone();
230 Box_::pin(crate::GioFuture::new(
231 self,
232 move |obj, cancellable, send| {
233 obj.lookup_by_address_async(&address, Some(cancellable), move |res| {
234 send.resolve(res);
235 });
236 },
237 ))
238 }
239
240 /// Synchronously resolves @hostname to determine its associated IP
241 /// address(es). @hostname may be an ASCII-only or UTF-8 hostname, or
242 /// the textual form of an IP address (in which case this just becomes
243 /// a wrapper around g_inet_address_new_from_string()).
244 ///
245 /// On success, g_resolver_lookup_by_name() will return a non-empty #GList of
246 /// #GInetAddress, sorted in order of preference and guaranteed to not
247 /// contain duplicates. That is, if using the result to connect to
248 /// @hostname, you should attempt to connect to the first address
249 /// first, then the second if the first fails, etc. If you are using
250 /// the result to listen on a socket, it is appropriate to add each
251 /// result using e.g. g_socket_listener_add_address().
252 ///
253 /// If the DNS resolution fails, @error (if non-[`None`]) will be set to a
254 /// value from #GResolverError and [`None`] will be returned.
255 ///
256 /// If @cancellable is non-[`None`], it can be used to cancel the
257 /// operation, in which case @error (if non-[`None`]) will be set to
258 /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
259 ///
260 /// If you are planning to connect to a socket on the resolved IP
261 /// address, it may be easier to create a #GNetworkAddress and use its
262 /// #GSocketConnectable interface.
263 /// ## `hostname`
264 /// the hostname to look up
265 /// ## `cancellable`
266 /// a #GCancellable, or [`None`]
267 ///
268 /// # Returns
269 ///
270 /// a non-empty #GList
271 /// of #GInetAddress, or [`None`] on error. You
272 /// must unref each of the addresses and free the list when you are
273 /// done with it. (You can use g_resolver_free_addresses() to do this.)
274 #[doc(alias = "g_resolver_lookup_by_name")]
275 fn lookup_by_name(
276 &self,
277 hostname: &str,
278 cancellable: Option<&impl IsA<Cancellable>>,
279 ) -> Result<Vec<InetAddress>, glib::Error> {
280 unsafe {
281 let mut error = std::ptr::null_mut();
282 let ret = ffi::g_resolver_lookup_by_name(
283 self.as_ref().to_glib_none().0,
284 hostname.to_glib_none().0,
285 cancellable.map(|p| p.as_ref()).to_glib_none().0,
286 &mut error,
287 );
288 if error.is_null() {
289 Ok(FromGlibPtrContainer::from_glib_full(ret))
290 } else {
291 Err(from_glib_full(error))
292 }
293 }
294 }
295
296 /// Begins asynchronously resolving @hostname to determine its
297 /// associated IP address(es), and eventually calls @callback, which
298 /// must call g_resolver_lookup_by_name_finish() to get the result.
299 /// See g_resolver_lookup_by_name() for more details.
300 /// ## `hostname`
301 /// the hostname to look up the address of
302 /// ## `cancellable`
303 /// a #GCancellable, or [`None`]
304 /// ## `callback`
305 /// callback to call after resolution completes
306 #[doc(alias = "g_resolver_lookup_by_name_async")]
307 fn lookup_by_name_async<P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static>(
308 &self,
309 hostname: &str,
310 cancellable: Option<&impl IsA<Cancellable>>,
311 callback: P,
312 ) {
313 let main_context = glib::MainContext::ref_thread_default();
314 let is_main_context_owner = main_context.is_owner();
315 let has_acquired_main_context = (!is_main_context_owner)
316 .then(|| main_context.acquire().ok())
317 .flatten();
318 assert!(
319 is_main_context_owner || has_acquired_main_context.is_some(),
320 "Async operations only allowed if the thread is owning the MainContext"
321 );
322
323 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
324 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
325 unsafe extern "C" fn lookup_by_name_async_trampoline<
326 P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
327 >(
328 _source_object: *mut glib::gobject_ffi::GObject,
329 res: *mut crate::ffi::GAsyncResult,
330 user_data: glib::ffi::gpointer,
331 ) {
332 let mut error = std::ptr::null_mut();
333 let ret =
334 ffi::g_resolver_lookup_by_name_finish(_source_object as *mut _, res, &mut error);
335 let result = if error.is_null() {
336 Ok(FromGlibPtrContainer::from_glib_full(ret))
337 } else {
338 Err(from_glib_full(error))
339 };
340 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
341 Box_::from_raw(user_data as *mut _);
342 let callback: P = callback.into_inner();
343 callback(result);
344 }
345 let callback = lookup_by_name_async_trampoline::<P>;
346 unsafe {
347 ffi::g_resolver_lookup_by_name_async(
348 self.as_ref().to_glib_none().0,
349 hostname.to_glib_none().0,
350 cancellable.map(|p| p.as_ref()).to_glib_none().0,
351 Some(callback),
352 Box_::into_raw(user_data) as *mut _,
353 );
354 }
355 }
356
357 fn lookup_by_name_future(
358 &self,
359 hostname: &str,
360 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
361 {
362 let hostname = String::from(hostname);
363 Box_::pin(crate::GioFuture::new(
364 self,
365 move |obj, cancellable, send| {
366 obj.lookup_by_name_async(&hostname, Some(cancellable), move |res| {
367 send.resolve(res);
368 });
369 },
370 ))
371 }
372
373 /// This differs from g_resolver_lookup_by_name() in that you can modify
374 /// the lookup behavior with @flags. For example this can be used to limit
375 /// results with [`ResolverNameLookupFlags::IPV4_ONLY`][crate::ResolverNameLookupFlags::IPV4_ONLY].
376 /// ## `hostname`
377 /// the hostname to look up
378 /// ## `flags`
379 /// extra #GResolverNameLookupFlags for the lookup
380 /// ## `cancellable`
381 /// a #GCancellable, or [`None`]
382 ///
383 /// # Returns
384 ///
385 /// a non-empty #GList
386 /// of #GInetAddress, or [`None`] on error. You
387 /// must unref each of the addresses and free the list when you are
388 /// done with it. (You can use g_resolver_free_addresses() to do this.)
389 #[cfg(feature = "v2_60")]
390 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
391 #[doc(alias = "g_resolver_lookup_by_name_with_flags")]
392 fn lookup_by_name_with_flags(
393 &self,
394 hostname: &str,
395 flags: ResolverNameLookupFlags,
396 cancellable: Option<&impl IsA<Cancellable>>,
397 ) -> Result<Vec<InetAddress>, glib::Error> {
398 unsafe {
399 let mut error = std::ptr::null_mut();
400 let ret = ffi::g_resolver_lookup_by_name_with_flags(
401 self.as_ref().to_glib_none().0,
402 hostname.to_glib_none().0,
403 flags.into_glib(),
404 cancellable.map(|p| p.as_ref()).to_glib_none().0,
405 &mut error,
406 );
407 if error.is_null() {
408 Ok(FromGlibPtrContainer::from_glib_full(ret))
409 } else {
410 Err(from_glib_full(error))
411 }
412 }
413 }
414
415 /// Begins asynchronously resolving @hostname to determine its
416 /// associated IP address(es), and eventually calls @callback, which
417 /// must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
418 /// See g_resolver_lookup_by_name() for more details.
419 /// ## `hostname`
420 /// the hostname to look up the address of
421 /// ## `flags`
422 /// extra #GResolverNameLookupFlags for the lookup
423 /// ## `cancellable`
424 /// a #GCancellable, or [`None`]
425 /// ## `callback`
426 /// callback to call after resolution completes
427 #[cfg(feature = "v2_60")]
428 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
429 #[doc(alias = "g_resolver_lookup_by_name_with_flags_async")]
430 fn lookup_by_name_with_flags_async<
431 P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
432 >(
433 &self,
434 hostname: &str,
435 flags: ResolverNameLookupFlags,
436 cancellable: Option<&impl IsA<Cancellable>>,
437 callback: P,
438 ) {
439 let main_context = glib::MainContext::ref_thread_default();
440 let is_main_context_owner = main_context.is_owner();
441 let has_acquired_main_context = (!is_main_context_owner)
442 .then(|| main_context.acquire().ok())
443 .flatten();
444 assert!(
445 is_main_context_owner || has_acquired_main_context.is_some(),
446 "Async operations only allowed if the thread is owning the MainContext"
447 );
448
449 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
450 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
451 unsafe extern "C" fn lookup_by_name_with_flags_async_trampoline<
452 P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
453 >(
454 _source_object: *mut glib::gobject_ffi::GObject,
455 res: *mut crate::ffi::GAsyncResult,
456 user_data: glib::ffi::gpointer,
457 ) {
458 let mut error = std::ptr::null_mut();
459 let ret = ffi::g_resolver_lookup_by_name_with_flags_finish(
460 _source_object as *mut _,
461 res,
462 &mut error,
463 );
464 let result = if error.is_null() {
465 Ok(FromGlibPtrContainer::from_glib_full(ret))
466 } else {
467 Err(from_glib_full(error))
468 };
469 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
470 Box_::from_raw(user_data as *mut _);
471 let callback: P = callback.into_inner();
472 callback(result);
473 }
474 let callback = lookup_by_name_with_flags_async_trampoline::<P>;
475 unsafe {
476 ffi::g_resolver_lookup_by_name_with_flags_async(
477 self.as_ref().to_glib_none().0,
478 hostname.to_glib_none().0,
479 flags.into_glib(),
480 cancellable.map(|p| p.as_ref()).to_glib_none().0,
481 Some(callback),
482 Box_::into_raw(user_data) as *mut _,
483 );
484 }
485 }
486
487 #[cfg(feature = "v2_60")]
488 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
489 fn lookup_by_name_with_flags_future(
490 &self,
491 hostname: &str,
492 flags: ResolverNameLookupFlags,
493 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
494 {
495 let hostname = String::from(hostname);
496 Box_::pin(crate::GioFuture::new(
497 self,
498 move |obj, cancellable, send| {
499 obj.lookup_by_name_with_flags_async(
500 &hostname,
501 flags,
502 Some(cancellable),
503 move |res| {
504 send.resolve(res);
505 },
506 );
507 },
508 ))
509 }
510
511 /// Synchronously performs a DNS record lookup for the given @rrname and returns
512 /// a list of records as #GVariant tuples. See #GResolverRecordType for
513 /// information on what the records contain for each @record_type.
514 ///
515 /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
516 /// a value from #GResolverError and [`None`] will be returned.
517 ///
518 /// If @cancellable is non-[`None`], it can be used to cancel the
519 /// operation, in which case @error (if non-[`None`]) will be set to
520 /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
521 /// ## `rrname`
522 /// the DNS name to look up the record for
523 /// ## `record_type`
524 /// the type of DNS record to look up
525 /// ## `cancellable`
526 /// a #GCancellable, or [`None`]
527 ///
528 /// # Returns
529 ///
530 /// a non-empty #GList of
531 /// #GVariant, or [`None`] on error. You must free each of the records and the list
532 /// when you are done with it. (You can use g_list_free_full() with
533 /// g_variant_unref() to do this.)
534 #[doc(alias = "g_resolver_lookup_records")]
535 fn lookup_records(
536 &self,
537 rrname: &str,
538 record_type: ResolverRecordType,
539 cancellable: Option<&impl IsA<Cancellable>>,
540 ) -> Result<Vec<glib::Variant>, glib::Error> {
541 unsafe {
542 let mut error = std::ptr::null_mut();
543 let ret = ffi::g_resolver_lookup_records(
544 self.as_ref().to_glib_none().0,
545 rrname.to_glib_none().0,
546 record_type.into_glib(),
547 cancellable.map(|p| p.as_ref()).to_glib_none().0,
548 &mut error,
549 );
550 if error.is_null() {
551 Ok(FromGlibPtrContainer::from_glib_full(ret))
552 } else {
553 Err(from_glib_full(error))
554 }
555 }
556 }
557
558 /// Begins asynchronously performing a DNS lookup for the given
559 /// @rrname, and eventually calls @callback, which must call
560 /// g_resolver_lookup_records_finish() to get the final result. See
561 /// g_resolver_lookup_records() for more details.
562 /// ## `rrname`
563 /// the DNS name to look up the record for
564 /// ## `record_type`
565 /// the type of DNS record to look up
566 /// ## `cancellable`
567 /// a #GCancellable, or [`None`]
568 /// ## `callback`
569 /// callback to call after resolution completes
570 #[doc(alias = "g_resolver_lookup_records_async")]
571 fn lookup_records_async<P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static>(
572 &self,
573 rrname: &str,
574 record_type: ResolverRecordType,
575 cancellable: Option<&impl IsA<Cancellable>>,
576 callback: P,
577 ) {
578 let main_context = glib::MainContext::ref_thread_default();
579 let is_main_context_owner = main_context.is_owner();
580 let has_acquired_main_context = (!is_main_context_owner)
581 .then(|| main_context.acquire().ok())
582 .flatten();
583 assert!(
584 is_main_context_owner || has_acquired_main_context.is_some(),
585 "Async operations only allowed if the thread is owning the MainContext"
586 );
587
588 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
589 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
590 unsafe extern "C" fn lookup_records_async_trampoline<
591 P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static,
592 >(
593 _source_object: *mut glib::gobject_ffi::GObject,
594 res: *mut crate::ffi::GAsyncResult,
595 user_data: glib::ffi::gpointer,
596 ) {
597 let mut error = std::ptr::null_mut();
598 let ret =
599 ffi::g_resolver_lookup_records_finish(_source_object as *mut _, res, &mut error);
600 let result = if error.is_null() {
601 Ok(FromGlibPtrContainer::from_glib_full(ret))
602 } else {
603 Err(from_glib_full(error))
604 };
605 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
606 Box_::from_raw(user_data as *mut _);
607 let callback: P = callback.into_inner();
608 callback(result);
609 }
610 let callback = lookup_records_async_trampoline::<P>;
611 unsafe {
612 ffi::g_resolver_lookup_records_async(
613 self.as_ref().to_glib_none().0,
614 rrname.to_glib_none().0,
615 record_type.into_glib(),
616 cancellable.map(|p| p.as_ref()).to_glib_none().0,
617 Some(callback),
618 Box_::into_raw(user_data) as *mut _,
619 );
620 }
621 }
622
623 fn lookup_records_future(
624 &self,
625 rrname: &str,
626 record_type: ResolverRecordType,
627 ) -> Pin<
628 Box_<dyn std::future::Future<Output = Result<Vec<glib::Variant>, glib::Error>> + 'static>,
629 > {
630 let rrname = String::from(rrname);
631 Box_::pin(crate::GioFuture::new(
632 self,
633 move |obj, cancellable, send| {
634 obj.lookup_records_async(&rrname, record_type, Some(cancellable), move |res| {
635 send.resolve(res);
636 });
637 },
638 ))
639 }
640
641 /// Synchronously performs a DNS SRV lookup for the given @service and
642 /// @protocol in the given @domain and returns an array of #GSrvTarget.
643 /// @domain may be an ASCII-only or UTF-8 hostname. Note also that the
644 /// @service and @protocol arguments do not include the leading underscore
645 /// that appears in the actual DNS entry.
646 ///
647 /// On success, g_resolver_lookup_service() will return a non-empty #GList of
648 /// #GSrvTarget, sorted in order of preference. (That is, you should
649 /// attempt to connect to the first target first, then the second if
650 /// the first fails, etc.)
651 ///
652 /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
653 /// a value from #GResolverError and [`None`] will be returned.
654 ///
655 /// If @cancellable is non-[`None`], it can be used to cancel the
656 /// operation, in which case @error (if non-[`None`]) will be set to
657 /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
658 ///
659 /// If you are planning to connect to the service, it is usually easier
660 /// to create a #GNetworkService and use its #GSocketConnectable
661 /// interface.
662 /// ## `service`
663 /// the service type to look up (eg, "ldap")
664 /// ## `protocol`
665 /// the networking protocol to use for @service (eg, "tcp")
666 /// ## `domain`
667 /// the DNS domain to look up the service in
668 /// ## `cancellable`
669 /// a #GCancellable, or [`None`]
670 ///
671 /// # Returns
672 ///
673 /// a non-empty #GList of
674 /// #GSrvTarget, or [`None`] on error. You must free each of the targets and the
675 /// list when you are done with it. (You can use g_resolver_free_targets() to do
676 /// this.)
677 #[doc(alias = "g_resolver_lookup_service")]
678 fn lookup_service(
679 &self,
680 service: &str,
681 protocol: &str,
682 domain: &str,
683 cancellable: Option<&impl IsA<Cancellable>>,
684 ) -> Result<Vec<SrvTarget>, glib::Error> {
685 unsafe {
686 let mut error = std::ptr::null_mut();
687 let ret = ffi::g_resolver_lookup_service(
688 self.as_ref().to_glib_none().0,
689 service.to_glib_none().0,
690 protocol.to_glib_none().0,
691 domain.to_glib_none().0,
692 cancellable.map(|p| p.as_ref()).to_glib_none().0,
693 &mut error,
694 );
695 if error.is_null() {
696 Ok(FromGlibPtrContainer::from_glib_full(ret))
697 } else {
698 Err(from_glib_full(error))
699 }
700 }
701 }
702
703 /// Begins asynchronously performing a DNS SRV lookup for the given
704 /// @service and @protocol in the given @domain, and eventually calls
705 /// @callback, which must call g_resolver_lookup_service_finish() to
706 /// get the final result. See g_resolver_lookup_service() for more
707 /// details.
708 /// ## `service`
709 /// the service type to look up (eg, "ldap")
710 /// ## `protocol`
711 /// the networking protocol to use for @service (eg, "tcp")
712 /// ## `domain`
713 /// the DNS domain to look up the service in
714 /// ## `cancellable`
715 /// a #GCancellable, or [`None`]
716 /// ## `callback`
717 /// callback to call after resolution completes
718 #[doc(alias = "g_resolver_lookup_service_async")]
719 fn lookup_service_async<P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static>(
720 &self,
721 service: &str,
722 protocol: &str,
723 domain: &str,
724 cancellable: Option<&impl IsA<Cancellable>>,
725 callback: P,
726 ) {
727 let main_context = glib::MainContext::ref_thread_default();
728 let is_main_context_owner = main_context.is_owner();
729 let has_acquired_main_context = (!is_main_context_owner)
730 .then(|| main_context.acquire().ok())
731 .flatten();
732 assert!(
733 is_main_context_owner || has_acquired_main_context.is_some(),
734 "Async operations only allowed if the thread is owning the MainContext"
735 );
736
737 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
738 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
739 unsafe extern "C" fn lookup_service_async_trampoline<
740 P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static,
741 >(
742 _source_object: *mut glib::gobject_ffi::GObject,
743 res: *mut crate::ffi::GAsyncResult,
744 user_data: glib::ffi::gpointer,
745 ) {
746 let mut error = std::ptr::null_mut();
747 let ret =
748 ffi::g_resolver_lookup_service_finish(_source_object as *mut _, res, &mut error);
749 let result = if error.is_null() {
750 Ok(FromGlibPtrContainer::from_glib_full(ret))
751 } else {
752 Err(from_glib_full(error))
753 };
754 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
755 Box_::from_raw(user_data as *mut _);
756 let callback: P = callback.into_inner();
757 callback(result);
758 }
759 let callback = lookup_service_async_trampoline::<P>;
760 unsafe {
761 ffi::g_resolver_lookup_service_async(
762 self.as_ref().to_glib_none().0,
763 service.to_glib_none().0,
764 protocol.to_glib_none().0,
765 domain.to_glib_none().0,
766 cancellable.map(|p| p.as_ref()).to_glib_none().0,
767 Some(callback),
768 Box_::into_raw(user_data) as *mut _,
769 );
770 }
771 }
772
773 fn lookup_service_future(
774 &self,
775 service: &str,
776 protocol: &str,
777 domain: &str,
778 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<SrvTarget>, glib::Error>> + 'static>>
779 {
780 let service = String::from(service);
781 let protocol = String::from(protocol);
782 let domain = String::from(domain);
783 Box_::pin(crate::GioFuture::new(
784 self,
785 move |obj, cancellable, send| {
786 obj.lookup_service_async(
787 &service,
788 &protocol,
789 &domain,
790 Some(cancellable),
791 move |res| {
792 send.resolve(res);
793 },
794 );
795 },
796 ))
797 }
798
799 /// Sets @self to be the application's default resolver (reffing
800 /// @self, and unreffing the previous default resolver, if any).
801 /// Future calls to g_resolver_get_default() will return this resolver.
802 ///
803 /// This can be used if an application wants to perform any sort of DNS
804 /// caching or "pinning"; it can implement its own #GResolver that
805 /// calls the original default resolver for DNS operations, and
806 /// implements its own cache policies on top of that, and then set
807 /// itself as the default resolver for all later code to use.
808 #[doc(alias = "g_resolver_set_default")]
809 fn set_default(&self) {
810 unsafe {
811 ffi::g_resolver_set_default(self.as_ref().to_glib_none().0);
812 }
813 }
814
815 /// Set the timeout applied to all resolver lookups. See #GResolver:timeout.
816 /// ## `timeout_ms`
817 /// timeout in milliseconds, or `0` for no timeouts
818 #[cfg(feature = "v2_78")]
819 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
820 #[doc(alias = "g_resolver_set_timeout")]
821 #[doc(alias = "timeout")]
822 fn set_timeout(&self, timeout_ms: u32) {
823 unsafe {
824 ffi::g_resolver_set_timeout(self.as_ref().to_glib_none().0, timeout_ms);
825 }
826 }
827
828 /// Emitted when the resolver notices that the system resolver
829 /// configuration has changed.
830 #[doc(alias = "reload")]
831 fn connect_reload<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
832 unsafe extern "C" fn reload_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
833 this: *mut ffi::GResolver,
834 f: glib::ffi::gpointer,
835 ) {
836 let f: &F = &*(f as *const F);
837 f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
838 }
839 unsafe {
840 let f: Box_<F> = Box_::new(f);
841 connect_raw(
842 self.as_ptr() as *mut _,
843 c"reload".as_ptr() as *const _,
844 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
845 reload_trampoline::<Self, F> as *const (),
846 )),
847 Box_::into_raw(f),
848 )
849 }
850 }
851
852 #[cfg(feature = "v2_78")]
853 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
854 #[doc(alias = "timeout")]
855 fn connect_timeout_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
856 unsafe extern "C" fn notify_timeout_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
857 this: *mut ffi::GResolver,
858 _param_spec: glib::ffi::gpointer,
859 f: glib::ffi::gpointer,
860 ) {
861 let f: &F = &*(f as *const F);
862 f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
863 }
864 unsafe {
865 let f: Box_<F> = Box_::new(f);
866 connect_raw(
867 self.as_ptr() as *mut _,
868 c"notify::timeout".as_ptr() as *const _,
869 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
870 notify_timeout_trampoline::<Self, F> as *const (),
871 )),
872 Box_::into_raw(f),
873 )
874 }
875 }
876}
877
878impl<O: IsA<Resolver>> ResolverExt for O {}