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 {}