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