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::{AsyncResult, Cancellable, InetAddress, ResolverRecordType, SrvTarget, ffi};
9use glib::{
10    object::ObjectType as _,
11    prelude::*,
12    signal::{SignalHandlerId, connect_raw},
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            unsafe {
200                let mut error = std::ptr::null_mut();
201                let ret = ffi::g_resolver_lookup_by_address_finish(
202                    _source_object as *mut _,
203                    res,
204                    &mut error,
205                );
206                let result = if error.is_null() {
207                    Ok(from_glib_full(ret))
208                } else {
209                    Err(from_glib_full(error))
210                };
211                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
212                    Box_::from_raw(user_data as *mut _);
213                let callback: P = callback.into_inner();
214                callback(result);
215            }
216        }
217        let callback = lookup_by_address_async_trampoline::<P>;
218        unsafe {
219            ffi::g_resolver_lookup_by_address_async(
220                self.as_ref().to_glib_none().0,
221                address.as_ref().to_glib_none().0,
222                cancellable.map(|p| p.as_ref()).to_glib_none().0,
223                Some(callback),
224                Box_::into_raw(user_data) as *mut _,
225            );
226        }
227    }
228
229    fn lookup_by_address_future(
230        &self,
231        address: &(impl IsA<InetAddress> + Clone + 'static),
232    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::GString, glib::Error>> + 'static>>
233    {
234        let address = address.clone();
235        Box_::pin(crate::GioFuture::new(
236            self,
237            move |obj, cancellable, send| {
238                obj.lookup_by_address_async(&address, Some(cancellable), move |res| {
239                    send.resolve(res);
240                });
241            },
242        ))
243    }
244
245    /// Synchronously resolves @hostname to determine its associated IP
246    /// address(es). @hostname may be an ASCII-only or UTF-8 hostname, or
247    /// the textual form of an IP address (in which case this just becomes
248    /// a wrapper around g_inet_address_new_from_string()).
249    ///
250    /// On success, g_resolver_lookup_by_name() will return a non-empty #GList of
251    /// #GInetAddress, sorted in order of preference and guaranteed to not
252    /// contain duplicates. That is, if using the result to connect to
253    /// @hostname, you should attempt to connect to the first address
254    /// first, then the second if the first fails, etc. If you are using
255    /// the result to listen on a socket, it is appropriate to add each
256    /// result using e.g. g_socket_listener_add_address().
257    ///
258    /// If the DNS resolution fails, @error (if non-[`None`]) will be set to a
259    /// value from #GResolverError and [`None`] will be returned.
260    ///
261    /// If @cancellable is non-[`None`], it can be used to cancel the
262    /// operation, in which case @error (if non-[`None`]) will be set to
263    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
264    ///
265    /// If you are planning to connect to a socket on the resolved IP
266    /// address, it may be easier to create a #GNetworkAddress and use its
267    /// #GSocketConnectable interface.
268    /// ## `hostname`
269    /// the hostname to look up
270    /// ## `cancellable`
271    /// a #GCancellable, or [`None`]
272    ///
273    /// # Returns
274    ///
275    /// a non-empty #GList
276    /// of #GInetAddress, or [`None`] on error. You
277    /// must unref each of the addresses and free the list when you are
278    /// done with it. (You can use g_resolver_free_addresses() to do this.)
279    #[doc(alias = "g_resolver_lookup_by_name")]
280    fn lookup_by_name(
281        &self,
282        hostname: &str,
283        cancellable: Option<&impl IsA<Cancellable>>,
284    ) -> Result<Vec<InetAddress>, glib::Error> {
285        unsafe {
286            let mut error = std::ptr::null_mut();
287            let ret = ffi::g_resolver_lookup_by_name(
288                self.as_ref().to_glib_none().0,
289                hostname.to_glib_none().0,
290                cancellable.map(|p| p.as_ref()).to_glib_none().0,
291                &mut error,
292            );
293            if error.is_null() {
294                Ok(FromGlibPtrContainer::from_glib_full(ret))
295            } else {
296                Err(from_glib_full(error))
297            }
298        }
299    }
300
301    /// Begins asynchronously resolving @hostname to determine its
302    /// associated IP address(es), and eventually calls @callback, which
303    /// must call g_resolver_lookup_by_name_finish() to get the result.
304    /// See g_resolver_lookup_by_name() for more details.
305    /// ## `hostname`
306    /// the hostname to look up the address of
307    /// ## `cancellable`
308    /// a #GCancellable, or [`None`]
309    /// ## `callback`
310    /// callback to call after resolution completes
311    #[doc(alias = "g_resolver_lookup_by_name_async")]
312    fn lookup_by_name_async<P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static>(
313        &self,
314        hostname: &str,
315        cancellable: Option<&impl IsA<Cancellable>>,
316        callback: P,
317    ) {
318        let main_context = glib::MainContext::ref_thread_default();
319        let is_main_context_owner = main_context.is_owner();
320        let has_acquired_main_context = (!is_main_context_owner)
321            .then(|| main_context.acquire().ok())
322            .flatten();
323        assert!(
324            is_main_context_owner || has_acquired_main_context.is_some(),
325            "Async operations only allowed if the thread is owning the MainContext"
326        );
327
328        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
329            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
330        unsafe extern "C" fn lookup_by_name_async_trampoline<
331            P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
332        >(
333            _source_object: *mut glib::gobject_ffi::GObject,
334            res: *mut crate::ffi::GAsyncResult,
335            user_data: glib::ffi::gpointer,
336        ) {
337            unsafe {
338                let mut error = std::ptr::null_mut();
339                let ret = ffi::g_resolver_lookup_by_name_finish(
340                    _source_object as *mut _,
341                    res,
342                    &mut error,
343                );
344                let result = if error.is_null() {
345                    Ok(FromGlibPtrContainer::from_glib_full(ret))
346                } else {
347                    Err(from_glib_full(error))
348                };
349                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
350                    Box_::from_raw(user_data as *mut _);
351                let callback: P = callback.into_inner();
352                callback(result);
353            }
354        }
355        let callback = lookup_by_name_async_trampoline::<P>;
356        unsafe {
357            ffi::g_resolver_lookup_by_name_async(
358                self.as_ref().to_glib_none().0,
359                hostname.to_glib_none().0,
360                cancellable.map(|p| p.as_ref()).to_glib_none().0,
361                Some(callback),
362                Box_::into_raw(user_data) as *mut _,
363            );
364        }
365    }
366
367    fn lookup_by_name_future(
368        &self,
369        hostname: &str,
370    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
371    {
372        let hostname = String::from(hostname);
373        Box_::pin(crate::GioFuture::new(
374            self,
375            move |obj, cancellable, send| {
376                obj.lookup_by_name_async(&hostname, Some(cancellable), move |res| {
377                    send.resolve(res);
378                });
379            },
380        ))
381    }
382
383    /// This differs from g_resolver_lookup_by_name() in that you can modify
384    /// the lookup behavior with @flags. For example this can be used to limit
385    /// results with [`ResolverNameLookupFlags::IPV4_ONLY`][crate::ResolverNameLookupFlags::IPV4_ONLY].
386    /// ## `hostname`
387    /// the hostname to look up
388    /// ## `flags`
389    /// extra #GResolverNameLookupFlags for the lookup
390    /// ## `cancellable`
391    /// a #GCancellable, or [`None`]
392    ///
393    /// # Returns
394    ///
395    /// a non-empty #GList
396    /// of #GInetAddress, or [`None`] on error. You
397    /// must unref each of the addresses and free the list when you are
398    /// done with it. (You can use g_resolver_free_addresses() to do this.)
399    #[cfg(feature = "v2_60")]
400    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
401    #[doc(alias = "g_resolver_lookup_by_name_with_flags")]
402    fn lookup_by_name_with_flags(
403        &self,
404        hostname: &str,
405        flags: ResolverNameLookupFlags,
406        cancellable: Option<&impl IsA<Cancellable>>,
407    ) -> Result<Vec<InetAddress>, glib::Error> {
408        unsafe {
409            let mut error = std::ptr::null_mut();
410            let ret = ffi::g_resolver_lookup_by_name_with_flags(
411                self.as_ref().to_glib_none().0,
412                hostname.to_glib_none().0,
413                flags.into_glib(),
414                cancellable.map(|p| p.as_ref()).to_glib_none().0,
415                &mut error,
416            );
417            if error.is_null() {
418                Ok(FromGlibPtrContainer::from_glib_full(ret))
419            } else {
420                Err(from_glib_full(error))
421            }
422        }
423    }
424
425    /// Begins asynchronously resolving @hostname to determine its
426    /// associated IP address(es), and eventually calls @callback, which
427    /// must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
428    /// See g_resolver_lookup_by_name() for more details.
429    /// ## `hostname`
430    /// the hostname to look up the address of
431    /// ## `flags`
432    /// extra #GResolverNameLookupFlags for the lookup
433    /// ## `cancellable`
434    /// a #GCancellable, or [`None`]
435    /// ## `callback`
436    /// callback to call after resolution completes
437    #[cfg(feature = "v2_60")]
438    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
439    #[doc(alias = "g_resolver_lookup_by_name_with_flags_async")]
440    fn lookup_by_name_with_flags_async<
441        P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
442    >(
443        &self,
444        hostname: &str,
445        flags: ResolverNameLookupFlags,
446        cancellable: Option<&impl IsA<Cancellable>>,
447        callback: P,
448    ) {
449        let main_context = glib::MainContext::ref_thread_default();
450        let is_main_context_owner = main_context.is_owner();
451        let has_acquired_main_context = (!is_main_context_owner)
452            .then(|| main_context.acquire().ok())
453            .flatten();
454        assert!(
455            is_main_context_owner || has_acquired_main_context.is_some(),
456            "Async operations only allowed if the thread is owning the MainContext"
457        );
458
459        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
460            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
461        unsafe extern "C" fn lookup_by_name_with_flags_async_trampoline<
462            P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
463        >(
464            _source_object: *mut glib::gobject_ffi::GObject,
465            res: *mut crate::ffi::GAsyncResult,
466            user_data: glib::ffi::gpointer,
467        ) {
468            unsafe {
469                let mut error = std::ptr::null_mut();
470                let ret = ffi::g_resolver_lookup_by_name_with_flags_finish(
471                    _source_object as *mut _,
472                    res,
473                    &mut error,
474                );
475                let result = if error.is_null() {
476                    Ok(FromGlibPtrContainer::from_glib_full(ret))
477                } else {
478                    Err(from_glib_full(error))
479                };
480                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
481                    Box_::from_raw(user_data as *mut _);
482                let callback: P = callback.into_inner();
483                callback(result);
484            }
485        }
486        let callback = lookup_by_name_with_flags_async_trampoline::<P>;
487        unsafe {
488            ffi::g_resolver_lookup_by_name_with_flags_async(
489                self.as_ref().to_glib_none().0,
490                hostname.to_glib_none().0,
491                flags.into_glib(),
492                cancellable.map(|p| p.as_ref()).to_glib_none().0,
493                Some(callback),
494                Box_::into_raw(user_data) as *mut _,
495            );
496        }
497    }
498
499    #[cfg(feature = "v2_60")]
500    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
501    fn lookup_by_name_with_flags_future(
502        &self,
503        hostname: &str,
504        flags: ResolverNameLookupFlags,
505    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
506    {
507        let hostname = String::from(hostname);
508        Box_::pin(crate::GioFuture::new(
509            self,
510            move |obj, cancellable, send| {
511                obj.lookup_by_name_with_flags_async(
512                    &hostname,
513                    flags,
514                    Some(cancellable),
515                    move |res| {
516                        send.resolve(res);
517                    },
518                );
519            },
520        ))
521    }
522
523    /// Synchronously performs a DNS record lookup for the given @rrname and returns
524    /// a list of records as #GVariant tuples. See #GResolverRecordType for
525    /// information on what the records contain for each @record_type.
526    ///
527    /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
528    /// a value from #GResolverError and [`None`] will be returned.
529    ///
530    /// If @cancellable is non-[`None`], it can be used to cancel the
531    /// operation, in which case @error (if non-[`None`]) will be set to
532    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
533    /// ## `rrname`
534    /// the DNS name to look up the record for
535    /// ## `record_type`
536    /// the type of DNS record to look up
537    /// ## `cancellable`
538    /// a #GCancellable, or [`None`]
539    ///
540    /// # Returns
541    ///
542    /// a non-empty #GList of
543    /// #GVariant, or [`None`] on error. You must free each of the records and the list
544    /// when you are done with it. (You can use g_list_free_full() with
545    /// g_variant_unref() to do this.)
546    #[doc(alias = "g_resolver_lookup_records")]
547    fn lookup_records(
548        &self,
549        rrname: &str,
550        record_type: ResolverRecordType,
551        cancellable: Option<&impl IsA<Cancellable>>,
552    ) -> Result<Vec<glib::Variant>, glib::Error> {
553        unsafe {
554            let mut error = std::ptr::null_mut();
555            let ret = ffi::g_resolver_lookup_records(
556                self.as_ref().to_glib_none().0,
557                rrname.to_glib_none().0,
558                record_type.into_glib(),
559                cancellable.map(|p| p.as_ref()).to_glib_none().0,
560                &mut error,
561            );
562            if error.is_null() {
563                Ok(FromGlibPtrContainer::from_glib_full(ret))
564            } else {
565                Err(from_glib_full(error))
566            }
567        }
568    }
569
570    /// Begins asynchronously performing a DNS lookup for the given
571    /// @rrname, and eventually calls @callback, which must call
572    /// g_resolver_lookup_records_finish() to get the final result. See
573    /// g_resolver_lookup_records() for more details.
574    /// ## `rrname`
575    /// the DNS name to look up the record for
576    /// ## `record_type`
577    /// the type of DNS record to look up
578    /// ## `cancellable`
579    /// a #GCancellable, or [`None`]
580    /// ## `callback`
581    /// callback to call after resolution completes
582    #[doc(alias = "g_resolver_lookup_records_async")]
583    fn lookup_records_async<P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static>(
584        &self,
585        rrname: &str,
586        record_type: ResolverRecordType,
587        cancellable: Option<&impl IsA<Cancellable>>,
588        callback: P,
589    ) {
590        let main_context = glib::MainContext::ref_thread_default();
591        let is_main_context_owner = main_context.is_owner();
592        let has_acquired_main_context = (!is_main_context_owner)
593            .then(|| main_context.acquire().ok())
594            .flatten();
595        assert!(
596            is_main_context_owner || has_acquired_main_context.is_some(),
597            "Async operations only allowed if the thread is owning the MainContext"
598        );
599
600        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
601            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
602        unsafe extern "C" fn lookup_records_async_trampoline<
603            P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static,
604        >(
605            _source_object: *mut glib::gobject_ffi::GObject,
606            res: *mut crate::ffi::GAsyncResult,
607            user_data: glib::ffi::gpointer,
608        ) {
609            unsafe {
610                let mut error = std::ptr::null_mut();
611                let ret = ffi::g_resolver_lookup_records_finish(
612                    _source_object as *mut _,
613                    res,
614                    &mut error,
615                );
616                let result = if error.is_null() {
617                    Ok(FromGlibPtrContainer::from_glib_full(ret))
618                } else {
619                    Err(from_glib_full(error))
620                };
621                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
622                    Box_::from_raw(user_data as *mut _);
623                let callback: P = callback.into_inner();
624                callback(result);
625            }
626        }
627        let callback = lookup_records_async_trampoline::<P>;
628        unsafe {
629            ffi::g_resolver_lookup_records_async(
630                self.as_ref().to_glib_none().0,
631                rrname.to_glib_none().0,
632                record_type.into_glib(),
633                cancellable.map(|p| p.as_ref()).to_glib_none().0,
634                Some(callback),
635                Box_::into_raw(user_data) as *mut _,
636            );
637        }
638    }
639
640    fn lookup_records_future(
641        &self,
642        rrname: &str,
643        record_type: ResolverRecordType,
644    ) -> Pin<
645        Box_<dyn std::future::Future<Output = Result<Vec<glib::Variant>, glib::Error>> + 'static>,
646    > {
647        let rrname = String::from(rrname);
648        Box_::pin(crate::GioFuture::new(
649            self,
650            move |obj, cancellable, send| {
651                obj.lookup_records_async(&rrname, record_type, Some(cancellable), move |res| {
652                    send.resolve(res);
653                });
654            },
655        ))
656    }
657
658    /// Synchronously performs a DNS SRV lookup for the given @service and
659    /// @protocol in the given @domain and returns an array of #GSrvTarget.
660    /// @domain may be an ASCII-only or UTF-8 hostname. Note also that the
661    /// @service and @protocol arguments do not include the leading underscore
662    /// that appears in the actual DNS entry.
663    ///
664    /// On success, g_resolver_lookup_service() will return a non-empty #GList of
665    /// #GSrvTarget, sorted in order of preference. (That is, you should
666    /// attempt to connect to the first target first, then the second if
667    /// the first fails, etc.)
668    ///
669    /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
670    /// a value from #GResolverError and [`None`] will be returned.
671    ///
672    /// If @cancellable is non-[`None`], it can be used to cancel the
673    /// operation, in which case @error (if non-[`None`]) will be set to
674    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
675    ///
676    /// If you are planning to connect to the service, it is usually easier
677    /// to create a #GNetworkService and use its #GSocketConnectable
678    /// interface.
679    /// ## `service`
680    /// the service type to look up (eg, "ldap")
681    /// ## `protocol`
682    /// the networking protocol to use for @service (eg, "tcp")
683    /// ## `domain`
684    /// the DNS domain to look up the service in
685    /// ## `cancellable`
686    /// a #GCancellable, or [`None`]
687    ///
688    /// # Returns
689    ///
690    /// a non-empty #GList of
691    /// #GSrvTarget, or [`None`] on error. You must free each of the targets and the
692    /// list when you are done with it. (You can use g_resolver_free_targets() to do
693    /// this.)
694    #[doc(alias = "g_resolver_lookup_service")]
695    fn lookup_service(
696        &self,
697        service: &str,
698        protocol: &str,
699        domain: &str,
700        cancellable: Option<&impl IsA<Cancellable>>,
701    ) -> Result<Vec<SrvTarget>, glib::Error> {
702        unsafe {
703            let mut error = std::ptr::null_mut();
704            let ret = ffi::g_resolver_lookup_service(
705                self.as_ref().to_glib_none().0,
706                service.to_glib_none().0,
707                protocol.to_glib_none().0,
708                domain.to_glib_none().0,
709                cancellable.map(|p| p.as_ref()).to_glib_none().0,
710                &mut error,
711            );
712            if error.is_null() {
713                Ok(FromGlibPtrContainer::from_glib_full(ret))
714            } else {
715                Err(from_glib_full(error))
716            }
717        }
718    }
719
720    /// Begins asynchronously performing a DNS SRV lookup for the given
721    /// @service and @protocol in the given @domain, and eventually calls
722    /// @callback, which must call g_resolver_lookup_service_finish() to
723    /// get the final result. See g_resolver_lookup_service() for more
724    /// details.
725    /// ## `service`
726    /// the service type to look up (eg, "ldap")
727    /// ## `protocol`
728    /// the networking protocol to use for @service (eg, "tcp")
729    /// ## `domain`
730    /// the DNS domain to look up the service in
731    /// ## `cancellable`
732    /// a #GCancellable, or [`None`]
733    /// ## `callback`
734    /// callback to call after resolution completes
735    #[doc(alias = "g_resolver_lookup_service_async")]
736    fn lookup_service_async<P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static>(
737        &self,
738        service: &str,
739        protocol: &str,
740        domain: &str,
741        cancellable: Option<&impl IsA<Cancellable>>,
742        callback: P,
743    ) {
744        let main_context = glib::MainContext::ref_thread_default();
745        let is_main_context_owner = main_context.is_owner();
746        let has_acquired_main_context = (!is_main_context_owner)
747            .then(|| main_context.acquire().ok())
748            .flatten();
749        assert!(
750            is_main_context_owner || has_acquired_main_context.is_some(),
751            "Async operations only allowed if the thread is owning the MainContext"
752        );
753
754        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
755            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
756        unsafe extern "C" fn lookup_service_async_trampoline<
757            P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static,
758        >(
759            _source_object: *mut glib::gobject_ffi::GObject,
760            res: *mut crate::ffi::GAsyncResult,
761            user_data: glib::ffi::gpointer,
762        ) {
763            unsafe {
764                let mut error = std::ptr::null_mut();
765                let ret = ffi::g_resolver_lookup_service_finish(
766                    _source_object as *mut _,
767                    res,
768                    &mut error,
769                );
770                let result = if error.is_null() {
771                    Ok(FromGlibPtrContainer::from_glib_full(ret))
772                } else {
773                    Err(from_glib_full(error))
774                };
775                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
776                    Box_::from_raw(user_data as *mut _);
777                let callback: P = callback.into_inner();
778                callback(result);
779            }
780        }
781        let callback = lookup_service_async_trampoline::<P>;
782        unsafe {
783            ffi::g_resolver_lookup_service_async(
784                self.as_ref().to_glib_none().0,
785                service.to_glib_none().0,
786                protocol.to_glib_none().0,
787                domain.to_glib_none().0,
788                cancellable.map(|p| p.as_ref()).to_glib_none().0,
789                Some(callback),
790                Box_::into_raw(user_data) as *mut _,
791            );
792        }
793    }
794
795    fn lookup_service_future(
796        &self,
797        service: &str,
798        protocol: &str,
799        domain: &str,
800    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<SrvTarget>, glib::Error>> + 'static>>
801    {
802        let service = String::from(service);
803        let protocol = String::from(protocol);
804        let domain = String::from(domain);
805        Box_::pin(crate::GioFuture::new(
806            self,
807            move |obj, cancellable, send| {
808                obj.lookup_service_async(
809                    &service,
810                    &protocol,
811                    &domain,
812                    Some(cancellable),
813                    move |res| {
814                        send.resolve(res);
815                    },
816                );
817            },
818        ))
819    }
820
821    /// Sets @self to be the application's default resolver (reffing
822    /// @self, and unreffing the previous default resolver, if any).
823    /// Future calls to g_resolver_get_default() will return this resolver.
824    ///
825    /// This can be used if an application wants to perform any sort of DNS
826    /// caching or "pinning"; it can implement its own #GResolver that
827    /// calls the original default resolver for DNS operations, and
828    /// implements its own cache policies on top of that, and then set
829    /// itself as the default resolver for all later code to use.
830    #[doc(alias = "g_resolver_set_default")]
831    fn set_default(&self) {
832        unsafe {
833            ffi::g_resolver_set_default(self.as_ref().to_glib_none().0);
834        }
835    }
836
837    /// Set the timeout applied to all resolver lookups. See #GResolver:timeout.
838    /// ## `timeout_ms`
839    /// timeout in milliseconds, or `0` for no timeouts
840    #[cfg(feature = "v2_78")]
841    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
842    #[doc(alias = "g_resolver_set_timeout")]
843    #[doc(alias = "timeout")]
844    fn set_timeout(&self, timeout_ms: u32) {
845        unsafe {
846            ffi::g_resolver_set_timeout(self.as_ref().to_glib_none().0, timeout_ms);
847        }
848    }
849
850    /// Emitted when the resolver notices that the system resolver
851    /// configuration has changed.
852    #[doc(alias = "reload")]
853    fn connect_reload<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
854        unsafe extern "C" fn reload_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
855            this: *mut ffi::GResolver,
856            f: glib::ffi::gpointer,
857        ) {
858            unsafe {
859                let f: &F = &*(f as *const F);
860                f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
861            }
862        }
863        unsafe {
864            let f: Box_<F> = Box_::new(f);
865            connect_raw(
866                self.as_ptr() as *mut _,
867                c"reload".as_ptr() as *const _,
868                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
869                    reload_trampoline::<Self, F> as *const (),
870                )),
871                Box_::into_raw(f),
872            )
873        }
874    }
875
876    #[cfg(feature = "v2_78")]
877    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
878    #[doc(alias = "timeout")]
879    fn connect_timeout_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
880        unsafe extern "C" fn notify_timeout_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
881            this: *mut ffi::GResolver,
882            _param_spec: glib::ffi::gpointer,
883            f: glib::ffi::gpointer,
884        ) {
885            unsafe {
886                let f: &F = &*(f as *const F);
887                f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
888            }
889        }
890        unsafe {
891            let f: Box_<F> = Box_::new(f);
892            connect_raw(
893                self.as_ptr() as *mut _,
894                c"notify::timeout".as_ptr() as *const _,
895                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
896                    notify_timeout_trampoline::<Self, F> as *const (),
897                )),
898                Box_::into_raw(f),
899            )
900        }
901    }
902}
903
904impl<O: IsA<Resolver>> ResolverExt for O {}