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
105mod sealed {
106    pub trait Sealed {}
107    impl<T: super::IsA<super::Resolver>> Sealed for T {}
108}
109
110/// Trait containing all [`struct@Resolver`] methods.
111///
112/// # Implementors
113///
114/// [`Resolver`][struct@crate::Resolver]
115pub trait ResolverExt: IsA<Resolver> + sealed::Sealed + 'static {
116    /// Get the timeout applied to all resolver lookups. See #GResolver:timeout.
117    ///
118    /// # Returns
119    ///
120    /// the resolver timeout, in milliseconds, or `0` for no timeout
121    #[cfg(feature = "v2_78")]
122    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
123    #[doc(alias = "g_resolver_get_timeout")]
124    #[doc(alias = "get_timeout")]
125    fn timeout(&self) -> u32 {
126        unsafe { ffi::g_resolver_get_timeout(self.as_ref().to_glib_none().0) }
127    }
128
129    /// Synchronously reverse-resolves @address to determine its
130    /// associated hostname.
131    ///
132    /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
133    /// a value from #GResolverError.
134    ///
135    /// If @cancellable is non-[`None`], it can be used to cancel the
136    /// operation, in which case @error (if non-[`None`]) will be set to
137    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
138    /// ## `address`
139    /// the address to reverse-resolve
140    /// ## `cancellable`
141    /// a #GCancellable, or [`None`]
142    ///
143    /// # Returns
144    ///
145    /// a hostname (either ASCII-only, or in ASCII-encoded
146    ///     form), or [`None`] on error.
147    #[doc(alias = "g_resolver_lookup_by_address")]
148    fn lookup_by_address(
149        &self,
150        address: &impl IsA<InetAddress>,
151        cancellable: Option<&impl IsA<Cancellable>>,
152    ) -> Result<glib::GString, glib::Error> {
153        unsafe {
154            let mut error = std::ptr::null_mut();
155            let ret = ffi::g_resolver_lookup_by_address(
156                self.as_ref().to_glib_none().0,
157                address.as_ref().to_glib_none().0,
158                cancellable.map(|p| p.as_ref()).to_glib_none().0,
159                &mut error,
160            );
161            if error.is_null() {
162                Ok(from_glib_full(ret))
163            } else {
164                Err(from_glib_full(error))
165            }
166        }
167    }
168
169    /// Begins asynchronously reverse-resolving @address to determine its
170    /// associated hostname, and eventually calls @callback, which must
171    /// call g_resolver_lookup_by_address_finish() to get the final result.
172    /// ## `address`
173    /// the address to reverse-resolve
174    /// ## `cancellable`
175    /// a #GCancellable, or [`None`]
176    /// ## `callback`
177    /// callback to call after resolution completes
178    #[doc(alias = "g_resolver_lookup_by_address_async")]
179    fn lookup_by_address_async<P: FnOnce(Result<glib::GString, glib::Error>) + 'static>(
180        &self,
181        address: &impl IsA<InetAddress>,
182        cancellable: Option<&impl IsA<Cancellable>>,
183        callback: P,
184    ) {
185        let main_context = glib::MainContext::ref_thread_default();
186        let is_main_context_owner = main_context.is_owner();
187        let has_acquired_main_context = (!is_main_context_owner)
188            .then(|| main_context.acquire().ok())
189            .flatten();
190        assert!(
191            is_main_context_owner || has_acquired_main_context.is_some(),
192            "Async operations only allowed if the thread is owning the MainContext"
193        );
194
195        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
196            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
197        unsafe extern "C" fn lookup_by_address_async_trampoline<
198            P: FnOnce(Result<glib::GString, glib::Error>) + 'static,
199        >(
200            _source_object: *mut glib::gobject_ffi::GObject,
201            res: *mut crate::ffi::GAsyncResult,
202            user_data: glib::ffi::gpointer,
203        ) {
204            let mut error = std::ptr::null_mut();
205            let ret =
206                ffi::g_resolver_lookup_by_address_finish(_source_object as *mut _, res, &mut error);
207            let result = if error.is_null() {
208                Ok(from_glib_full(ret))
209            } else {
210                Err(from_glib_full(error))
211            };
212            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
213                Box_::from_raw(user_data as *mut _);
214            let callback: P = callback.into_inner();
215            callback(result);
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            let mut error = std::ptr::null_mut();
338            let ret =
339                ffi::g_resolver_lookup_by_name_finish(_source_object as *mut _, res, &mut error);
340            let result = if error.is_null() {
341                Ok(FromGlibPtrContainer::from_glib_full(ret))
342            } else {
343                Err(from_glib_full(error))
344            };
345            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
346                Box_::from_raw(user_data as *mut _);
347            let callback: P = callback.into_inner();
348            callback(result);
349        }
350        let callback = lookup_by_name_async_trampoline::<P>;
351        unsafe {
352            ffi::g_resolver_lookup_by_name_async(
353                self.as_ref().to_glib_none().0,
354                hostname.to_glib_none().0,
355                cancellable.map(|p| p.as_ref()).to_glib_none().0,
356                Some(callback),
357                Box_::into_raw(user_data) as *mut _,
358            );
359        }
360    }
361
362    fn lookup_by_name_future(
363        &self,
364        hostname: &str,
365    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
366    {
367        let hostname = String::from(hostname);
368        Box_::pin(crate::GioFuture::new(
369            self,
370            move |obj, cancellable, send| {
371                obj.lookup_by_name_async(&hostname, Some(cancellable), move |res| {
372                    send.resolve(res);
373                });
374            },
375        ))
376    }
377
378    /// This differs from g_resolver_lookup_by_name() in that you can modify
379    /// the lookup behavior with @flags. For example this can be used to limit
380    /// results with [`ResolverNameLookupFlags::IPV4_ONLY`][crate::ResolverNameLookupFlags::IPV4_ONLY].
381    /// ## `hostname`
382    /// the hostname to look up
383    /// ## `flags`
384    /// extra #GResolverNameLookupFlags for the lookup
385    /// ## `cancellable`
386    /// a #GCancellable, or [`None`]
387    ///
388    /// # Returns
389    ///
390    /// a non-empty #GList
391    /// of #GInetAddress, or [`None`] on error. You
392    /// must unref each of the addresses and free the list when you are
393    /// done with it. (You can use g_resolver_free_addresses() to do this.)
394    #[cfg(feature = "v2_60")]
395    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
396    #[doc(alias = "g_resolver_lookup_by_name_with_flags")]
397    fn lookup_by_name_with_flags(
398        &self,
399        hostname: &str,
400        flags: ResolverNameLookupFlags,
401        cancellable: Option<&impl IsA<Cancellable>>,
402    ) -> Result<Vec<InetAddress>, glib::Error> {
403        unsafe {
404            let mut error = std::ptr::null_mut();
405            let ret = ffi::g_resolver_lookup_by_name_with_flags(
406                self.as_ref().to_glib_none().0,
407                hostname.to_glib_none().0,
408                flags.into_glib(),
409                cancellable.map(|p| p.as_ref()).to_glib_none().0,
410                &mut error,
411            );
412            if error.is_null() {
413                Ok(FromGlibPtrContainer::from_glib_full(ret))
414            } else {
415                Err(from_glib_full(error))
416            }
417        }
418    }
419
420    /// Begins asynchronously resolving @hostname to determine its
421    /// associated IP address(es), and eventually calls @callback, which
422    /// must call g_resolver_lookup_by_name_with_flags_finish() to get the result.
423    /// See g_resolver_lookup_by_name() for more details.
424    /// ## `hostname`
425    /// the hostname to look up the address of
426    /// ## `flags`
427    /// extra #GResolverNameLookupFlags for the lookup
428    /// ## `cancellable`
429    /// a #GCancellable, or [`None`]
430    /// ## `callback`
431    /// callback to call after resolution completes
432    #[cfg(feature = "v2_60")]
433    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
434    #[doc(alias = "g_resolver_lookup_by_name_with_flags_async")]
435    fn lookup_by_name_with_flags_async<
436        P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
437    >(
438        &self,
439        hostname: &str,
440        flags: ResolverNameLookupFlags,
441        cancellable: Option<&impl IsA<Cancellable>>,
442        callback: P,
443    ) {
444        let main_context = glib::MainContext::ref_thread_default();
445        let is_main_context_owner = main_context.is_owner();
446        let has_acquired_main_context = (!is_main_context_owner)
447            .then(|| main_context.acquire().ok())
448            .flatten();
449        assert!(
450            is_main_context_owner || has_acquired_main_context.is_some(),
451            "Async operations only allowed if the thread is owning the MainContext"
452        );
453
454        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
455            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
456        unsafe extern "C" fn lookup_by_name_with_flags_async_trampoline<
457            P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
458        >(
459            _source_object: *mut glib::gobject_ffi::GObject,
460            res: *mut crate::ffi::GAsyncResult,
461            user_data: glib::ffi::gpointer,
462        ) {
463            let mut error = std::ptr::null_mut();
464            let ret = ffi::g_resolver_lookup_by_name_with_flags_finish(
465                _source_object as *mut _,
466                res,
467                &mut error,
468            );
469            let result = if error.is_null() {
470                Ok(FromGlibPtrContainer::from_glib_full(ret))
471            } else {
472                Err(from_glib_full(error))
473            };
474            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
475                Box_::from_raw(user_data as *mut _);
476            let callback: P = callback.into_inner();
477            callback(result);
478        }
479        let callback = lookup_by_name_with_flags_async_trampoline::<P>;
480        unsafe {
481            ffi::g_resolver_lookup_by_name_with_flags_async(
482                self.as_ref().to_glib_none().0,
483                hostname.to_glib_none().0,
484                flags.into_glib(),
485                cancellable.map(|p| p.as_ref()).to_glib_none().0,
486                Some(callback),
487                Box_::into_raw(user_data) as *mut _,
488            );
489        }
490    }
491
492    #[cfg(feature = "v2_60")]
493    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
494    fn lookup_by_name_with_flags_future(
495        &self,
496        hostname: &str,
497        flags: ResolverNameLookupFlags,
498    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
499    {
500        let hostname = String::from(hostname);
501        Box_::pin(crate::GioFuture::new(
502            self,
503            move |obj, cancellable, send| {
504                obj.lookup_by_name_with_flags_async(
505                    &hostname,
506                    flags,
507                    Some(cancellable),
508                    move |res| {
509                        send.resolve(res);
510                    },
511                );
512            },
513        ))
514    }
515
516    /// Synchronously performs a DNS record lookup for the given @rrname and returns
517    /// a list of records as #GVariant tuples. See #GResolverRecordType for
518    /// information on what the records contain for each @record_type.
519    ///
520    /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
521    /// a value from #GResolverError and [`None`] will be returned.
522    ///
523    /// If @cancellable is non-[`None`], it can be used to cancel the
524    /// operation, in which case @error (if non-[`None`]) will be set to
525    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
526    /// ## `rrname`
527    /// the DNS name to look up the record for
528    /// ## `record_type`
529    /// the type of DNS record to look up
530    /// ## `cancellable`
531    /// a #GCancellable, or [`None`]
532    ///
533    /// # Returns
534    ///
535    /// a non-empty #GList of
536    /// #GVariant, or [`None`] on error. You must free each of the records and the list
537    /// when you are done with it. (You can use g_list_free_full() with
538    /// g_variant_unref() to do this.)
539    #[doc(alias = "g_resolver_lookup_records")]
540    fn lookup_records(
541        &self,
542        rrname: &str,
543        record_type: ResolverRecordType,
544        cancellable: Option<&impl IsA<Cancellable>>,
545    ) -> Result<Vec<glib::Variant>, glib::Error> {
546        unsafe {
547            let mut error = std::ptr::null_mut();
548            let ret = ffi::g_resolver_lookup_records(
549                self.as_ref().to_glib_none().0,
550                rrname.to_glib_none().0,
551                record_type.into_glib(),
552                cancellable.map(|p| p.as_ref()).to_glib_none().0,
553                &mut error,
554            );
555            if error.is_null() {
556                Ok(FromGlibPtrContainer::from_glib_full(ret))
557            } else {
558                Err(from_glib_full(error))
559            }
560        }
561    }
562
563    /// Begins asynchronously performing a DNS lookup for the given
564    /// @rrname, and eventually calls @callback, which must call
565    /// g_resolver_lookup_records_finish() to get the final result. See
566    /// g_resolver_lookup_records() for more details.
567    /// ## `rrname`
568    /// the DNS name to look up the record for
569    /// ## `record_type`
570    /// the type of DNS record to look up
571    /// ## `cancellable`
572    /// a #GCancellable, or [`None`]
573    /// ## `callback`
574    /// callback to call after resolution completes
575    #[doc(alias = "g_resolver_lookup_records_async")]
576    fn lookup_records_async<P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static>(
577        &self,
578        rrname: &str,
579        record_type: ResolverRecordType,
580        cancellable: Option<&impl IsA<Cancellable>>,
581        callback: P,
582    ) {
583        let main_context = glib::MainContext::ref_thread_default();
584        let is_main_context_owner = main_context.is_owner();
585        let has_acquired_main_context = (!is_main_context_owner)
586            .then(|| main_context.acquire().ok())
587            .flatten();
588        assert!(
589            is_main_context_owner || has_acquired_main_context.is_some(),
590            "Async operations only allowed if the thread is owning the MainContext"
591        );
592
593        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
594            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
595        unsafe extern "C" fn lookup_records_async_trampoline<
596            P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static,
597        >(
598            _source_object: *mut glib::gobject_ffi::GObject,
599            res: *mut crate::ffi::GAsyncResult,
600            user_data: glib::ffi::gpointer,
601        ) {
602            let mut error = std::ptr::null_mut();
603            let ret =
604                ffi::g_resolver_lookup_records_finish(_source_object as *mut _, res, &mut error);
605            let result = if error.is_null() {
606                Ok(FromGlibPtrContainer::from_glib_full(ret))
607            } else {
608                Err(from_glib_full(error))
609            };
610            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
611                Box_::from_raw(user_data as *mut _);
612            let callback: P = callback.into_inner();
613            callback(result);
614        }
615        let callback = lookup_records_async_trampoline::<P>;
616        unsafe {
617            ffi::g_resolver_lookup_records_async(
618                self.as_ref().to_glib_none().0,
619                rrname.to_glib_none().0,
620                record_type.into_glib(),
621                cancellable.map(|p| p.as_ref()).to_glib_none().0,
622                Some(callback),
623                Box_::into_raw(user_data) as *mut _,
624            );
625        }
626    }
627
628    fn lookup_records_future(
629        &self,
630        rrname: &str,
631        record_type: ResolverRecordType,
632    ) -> Pin<
633        Box_<dyn std::future::Future<Output = Result<Vec<glib::Variant>, glib::Error>> + 'static>,
634    > {
635        let rrname = String::from(rrname);
636        Box_::pin(crate::GioFuture::new(
637            self,
638            move |obj, cancellable, send| {
639                obj.lookup_records_async(&rrname, record_type, Some(cancellable), move |res| {
640                    send.resolve(res);
641                });
642            },
643        ))
644    }
645
646    /// Synchronously performs a DNS SRV lookup for the given @service and
647    /// @protocol in the given @domain and returns an array of #GSrvTarget.
648    /// @domain may be an ASCII-only or UTF-8 hostname. Note also that the
649    /// @service and @protocol arguments do not include the leading underscore
650    /// that appears in the actual DNS entry.
651    ///
652    /// On success, g_resolver_lookup_service() will return a non-empty #GList of
653    /// #GSrvTarget, sorted in order of preference. (That is, you should
654    /// attempt to connect to the first target first, then the second if
655    /// the first fails, etc.)
656    ///
657    /// If the DNS resolution fails, @error (if non-[`None`]) will be set to
658    /// a value from #GResolverError and [`None`] will be returned.
659    ///
660    /// If @cancellable is non-[`None`], it can be used to cancel the
661    /// operation, in which case @error (if non-[`None`]) will be set to
662    /// [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled].
663    ///
664    /// If you are planning to connect to the service, it is usually easier
665    /// to create a #GNetworkService and use its #GSocketConnectable
666    /// interface.
667    /// ## `service`
668    /// the service type to look up (eg, "ldap")
669    /// ## `protocol`
670    /// the networking protocol to use for @service (eg, "tcp")
671    /// ## `domain`
672    /// the DNS domain to look up the service in
673    /// ## `cancellable`
674    /// a #GCancellable, or [`None`]
675    ///
676    /// # Returns
677    ///
678    /// a non-empty #GList of
679    /// #GSrvTarget, or [`None`] on error. You must free each of the targets and the
680    /// list when you are done with it. (You can use g_resolver_free_targets() to do
681    /// this.)
682    #[doc(alias = "g_resolver_lookup_service")]
683    fn lookup_service(
684        &self,
685        service: &str,
686        protocol: &str,
687        domain: &str,
688        cancellable: Option<&impl IsA<Cancellable>>,
689    ) -> Result<Vec<SrvTarget>, glib::Error> {
690        unsafe {
691            let mut error = std::ptr::null_mut();
692            let ret = ffi::g_resolver_lookup_service(
693                self.as_ref().to_glib_none().0,
694                service.to_glib_none().0,
695                protocol.to_glib_none().0,
696                domain.to_glib_none().0,
697                cancellable.map(|p| p.as_ref()).to_glib_none().0,
698                &mut error,
699            );
700            if error.is_null() {
701                Ok(FromGlibPtrContainer::from_glib_full(ret))
702            } else {
703                Err(from_glib_full(error))
704            }
705        }
706    }
707
708    /// Begins asynchronously performing a DNS SRV lookup for the given
709    /// @service and @protocol in the given @domain, and eventually calls
710    /// @callback, which must call g_resolver_lookup_service_finish() to
711    /// get the final result. See g_resolver_lookup_service() for more
712    /// details.
713    /// ## `service`
714    /// the service type to look up (eg, "ldap")
715    /// ## `protocol`
716    /// the networking protocol to use for @service (eg, "tcp")
717    /// ## `domain`
718    /// the DNS domain to look up the service in
719    /// ## `cancellable`
720    /// a #GCancellable, or [`None`]
721    /// ## `callback`
722    /// callback to call after resolution completes
723    #[doc(alias = "g_resolver_lookup_service_async")]
724    fn lookup_service_async<P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static>(
725        &self,
726        service: &str,
727        protocol: &str,
728        domain: &str,
729        cancellable: Option<&impl IsA<Cancellable>>,
730        callback: P,
731    ) {
732        let main_context = glib::MainContext::ref_thread_default();
733        let is_main_context_owner = main_context.is_owner();
734        let has_acquired_main_context = (!is_main_context_owner)
735            .then(|| main_context.acquire().ok())
736            .flatten();
737        assert!(
738            is_main_context_owner || has_acquired_main_context.is_some(),
739            "Async operations only allowed if the thread is owning the MainContext"
740        );
741
742        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
743            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
744        unsafe extern "C" fn lookup_service_async_trampoline<
745            P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static,
746        >(
747            _source_object: *mut glib::gobject_ffi::GObject,
748            res: *mut crate::ffi::GAsyncResult,
749            user_data: glib::ffi::gpointer,
750        ) {
751            let mut error = std::ptr::null_mut();
752            let ret =
753                ffi::g_resolver_lookup_service_finish(_source_object as *mut _, res, &mut error);
754            let result = if error.is_null() {
755                Ok(FromGlibPtrContainer::from_glib_full(ret))
756            } else {
757                Err(from_glib_full(error))
758            };
759            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
760                Box_::from_raw(user_data as *mut _);
761            let callback: P = callback.into_inner();
762            callback(result);
763        }
764        let callback = lookup_service_async_trampoline::<P>;
765        unsafe {
766            ffi::g_resolver_lookup_service_async(
767                self.as_ref().to_glib_none().0,
768                service.to_glib_none().0,
769                protocol.to_glib_none().0,
770                domain.to_glib_none().0,
771                cancellable.map(|p| p.as_ref()).to_glib_none().0,
772                Some(callback),
773                Box_::into_raw(user_data) as *mut _,
774            );
775        }
776    }
777
778    fn lookup_service_future(
779        &self,
780        service: &str,
781        protocol: &str,
782        domain: &str,
783    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<SrvTarget>, glib::Error>> + 'static>>
784    {
785        let service = String::from(service);
786        let protocol = String::from(protocol);
787        let domain = String::from(domain);
788        Box_::pin(crate::GioFuture::new(
789            self,
790            move |obj, cancellable, send| {
791                obj.lookup_service_async(
792                    &service,
793                    &protocol,
794                    &domain,
795                    Some(cancellable),
796                    move |res| {
797                        send.resolve(res);
798                    },
799                );
800            },
801        ))
802    }
803
804    /// Sets @self to be the application's default resolver (reffing
805    /// @self, and unreffing the previous default resolver, if any).
806    /// Future calls to g_resolver_get_default() will return this resolver.
807    ///
808    /// This can be used if an application wants to perform any sort of DNS
809    /// caching or "pinning"; it can implement its own #GResolver that
810    /// calls the original default resolver for DNS operations, and
811    /// implements its own cache policies on top of that, and then set
812    /// itself as the default resolver for all later code to use.
813    #[doc(alias = "g_resolver_set_default")]
814    fn set_default(&self) {
815        unsafe {
816            ffi::g_resolver_set_default(self.as_ref().to_glib_none().0);
817        }
818    }
819
820    /// Set the timeout applied to all resolver lookups. See #GResolver:timeout.
821    /// ## `timeout_ms`
822    /// timeout in milliseconds, or `0` for no timeouts
823    #[cfg(feature = "v2_78")]
824    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
825    #[doc(alias = "g_resolver_set_timeout")]
826    #[doc(alias = "timeout")]
827    fn set_timeout(&self, timeout_ms: u32) {
828        unsafe {
829            ffi::g_resolver_set_timeout(self.as_ref().to_glib_none().0, timeout_ms);
830        }
831    }
832
833    /// Emitted when the resolver notices that the system resolver
834    /// configuration has changed.
835    #[doc(alias = "reload")]
836    fn connect_reload<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
837        unsafe extern "C" fn reload_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
838            this: *mut ffi::GResolver,
839            f: glib::ffi::gpointer,
840        ) {
841            let f: &F = &*(f as *const F);
842            f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
843        }
844        unsafe {
845            let f: Box_<F> = Box_::new(f);
846            connect_raw(
847                self.as_ptr() as *mut _,
848                b"reload\0".as_ptr() as *const _,
849                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
850                    reload_trampoline::<Self, F> as *const (),
851                )),
852                Box_::into_raw(f),
853            )
854        }
855    }
856
857    #[cfg(feature = "v2_78")]
858    #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
859    #[doc(alias = "timeout")]
860    fn connect_timeout_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
861        unsafe extern "C" fn notify_timeout_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
862            this: *mut ffi::GResolver,
863            _param_spec: glib::ffi::gpointer,
864            f: glib::ffi::gpointer,
865        ) {
866            let f: &F = &*(f as *const F);
867            f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
868        }
869        unsafe {
870            let f: Box_<F> = Box_::new(f);
871            connect_raw(
872                self.as_ptr() as *mut _,
873                b"notify::timeout\0".as_ptr() as *const _,
874                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
875                    notify_timeout_trampoline::<Self, F> as *const (),
876                )),
877                Box_::into_raw(f),
878            )
879        }
880    }
881}
882
883impl<O: IsA<Resolver>> ResolverExt for O {}