1#[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 #[doc(alias = "GResolver")]
19 pub struct Resolver(Object<ffi::GResolver, ffi::GResolverClass>);
20
21 match fn {
22 type_ => || ffi::g_resolver_get_type(),
23 }
24}
25
26impl Resolver {
27 pub const NONE: Option<&'static Resolver> = None;
28
29 #[doc(alias = "g_resolver_get_default")]
40 #[doc(alias = "get_default")]
41 #[allow(clippy::should_implement_trait)]
42 pub fn default() -> Resolver {
43 unsafe { from_glib_full(ffi::g_resolver_get_default()) }
44 }
45}
46
47pub trait ResolverExt: IsA<Resolver> + 'static {
48 #[cfg(feature = "v2_78")]
49 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
50 #[doc(alias = "g_resolver_get_timeout")]
51 #[doc(alias = "get_timeout")]
52 fn timeout(&self) -> u32 {
53 unsafe { ffi::g_resolver_get_timeout(self.as_ref().to_glib_none().0) }
54 }
55
56 #[doc(alias = "g_resolver_lookup_by_address")]
57 fn lookup_by_address(
58 &self,
59 address: &impl IsA<InetAddress>,
60 cancellable: Option<&impl IsA<Cancellable>>,
61 ) -> Result<glib::GString, glib::Error> {
62 unsafe {
63 let mut error = std::ptr::null_mut();
64 let ret = ffi::g_resolver_lookup_by_address(
65 self.as_ref().to_glib_none().0,
66 address.as_ref().to_glib_none().0,
67 cancellable.map(|p| p.as_ref()).to_glib_none().0,
68 &mut error,
69 );
70 if error.is_null() {
71 Ok(from_glib_full(ret))
72 } else {
73 Err(from_glib_full(error))
74 }
75 }
76 }
77
78 #[doc(alias = "g_resolver_lookup_by_address_async")]
79 fn lookup_by_address_async<P: FnOnce(Result<glib::GString, glib::Error>) + 'static>(
80 &self,
81 address: &impl IsA<InetAddress>,
82 cancellable: Option<&impl IsA<Cancellable>>,
83 callback: P,
84 ) {
85 let main_context = glib::MainContext::ref_thread_default();
86 let is_main_context_owner = main_context.is_owner();
87 let has_acquired_main_context = (!is_main_context_owner)
88 .then(|| main_context.acquire().ok())
89 .flatten();
90 assert!(
91 is_main_context_owner || has_acquired_main_context.is_some(),
92 "Async operations only allowed if the thread is owning the MainContext"
93 );
94
95 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
96 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
97 unsafe extern "C" fn lookup_by_address_async_trampoline<
98 P: FnOnce(Result<glib::GString, glib::Error>) + 'static,
99 >(
100 _source_object: *mut glib::gobject_ffi::GObject,
101 res: *mut crate::ffi::GAsyncResult,
102 user_data: glib::ffi::gpointer,
103 ) {
104 let mut error = std::ptr::null_mut();
105 let ret =
106 ffi::g_resolver_lookup_by_address_finish(_source_object as *mut _, res, &mut error);
107 let result = if error.is_null() {
108 Ok(from_glib_full(ret))
109 } else {
110 Err(from_glib_full(error))
111 };
112 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
113 Box_::from_raw(user_data as *mut _);
114 let callback: P = callback.into_inner();
115 callback(result);
116 }
117 let callback = lookup_by_address_async_trampoline::<P>;
118 unsafe {
119 ffi::g_resolver_lookup_by_address_async(
120 self.as_ref().to_glib_none().0,
121 address.as_ref().to_glib_none().0,
122 cancellable.map(|p| p.as_ref()).to_glib_none().0,
123 Some(callback),
124 Box_::into_raw(user_data) as *mut _,
125 );
126 }
127 }
128
129 fn lookup_by_address_future(
130 &self,
131 address: &(impl IsA<InetAddress> + Clone + 'static),
132 ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::GString, glib::Error>> + 'static>>
133 {
134 let address = address.clone();
135 Box_::pin(crate::GioFuture::new(
136 self,
137 move |obj, cancellable, send| {
138 obj.lookup_by_address_async(&address, Some(cancellable), move |res| {
139 send.resolve(res);
140 });
141 },
142 ))
143 }
144
145 #[doc(alias = "g_resolver_lookup_by_name")]
146 fn lookup_by_name(
147 &self,
148 hostname: &str,
149 cancellable: Option<&impl IsA<Cancellable>>,
150 ) -> Result<Vec<InetAddress>, glib::Error> {
151 unsafe {
152 let mut error = std::ptr::null_mut();
153 let ret = ffi::g_resolver_lookup_by_name(
154 self.as_ref().to_glib_none().0,
155 hostname.to_glib_none().0,
156 cancellable.map(|p| p.as_ref()).to_glib_none().0,
157 &mut error,
158 );
159 if error.is_null() {
160 Ok(FromGlibPtrContainer::from_glib_full(ret))
161 } else {
162 Err(from_glib_full(error))
163 }
164 }
165 }
166
167 #[doc(alias = "g_resolver_lookup_by_name_async")]
168 fn lookup_by_name_async<P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static>(
169 &self,
170 hostname: &str,
171 cancellable: Option<&impl IsA<Cancellable>>,
172 callback: P,
173 ) {
174 let main_context = glib::MainContext::ref_thread_default();
175 let is_main_context_owner = main_context.is_owner();
176 let has_acquired_main_context = (!is_main_context_owner)
177 .then(|| main_context.acquire().ok())
178 .flatten();
179 assert!(
180 is_main_context_owner || has_acquired_main_context.is_some(),
181 "Async operations only allowed if the thread is owning the MainContext"
182 );
183
184 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
185 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
186 unsafe extern "C" fn lookup_by_name_async_trampoline<
187 P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
188 >(
189 _source_object: *mut glib::gobject_ffi::GObject,
190 res: *mut crate::ffi::GAsyncResult,
191 user_data: glib::ffi::gpointer,
192 ) {
193 let mut error = std::ptr::null_mut();
194 let ret =
195 ffi::g_resolver_lookup_by_name_finish(_source_object as *mut _, res, &mut error);
196 let result = if error.is_null() {
197 Ok(FromGlibPtrContainer::from_glib_full(ret))
198 } else {
199 Err(from_glib_full(error))
200 };
201 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
202 Box_::from_raw(user_data as *mut _);
203 let callback: P = callback.into_inner();
204 callback(result);
205 }
206 let callback = lookup_by_name_async_trampoline::<P>;
207 unsafe {
208 ffi::g_resolver_lookup_by_name_async(
209 self.as_ref().to_glib_none().0,
210 hostname.to_glib_none().0,
211 cancellable.map(|p| p.as_ref()).to_glib_none().0,
212 Some(callback),
213 Box_::into_raw(user_data) as *mut _,
214 );
215 }
216 }
217
218 fn lookup_by_name_future(
219 &self,
220 hostname: &str,
221 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
222 {
223 let hostname = String::from(hostname);
224 Box_::pin(crate::GioFuture::new(
225 self,
226 move |obj, cancellable, send| {
227 obj.lookup_by_name_async(&hostname, Some(cancellable), move |res| {
228 send.resolve(res);
229 });
230 },
231 ))
232 }
233
234 #[cfg(feature = "v2_60")]
235 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
236 #[doc(alias = "g_resolver_lookup_by_name_with_flags")]
237 fn lookup_by_name_with_flags(
238 &self,
239 hostname: &str,
240 flags: ResolverNameLookupFlags,
241 cancellable: Option<&impl IsA<Cancellable>>,
242 ) -> Result<Vec<InetAddress>, glib::Error> {
243 unsafe {
244 let mut error = std::ptr::null_mut();
245 let ret = ffi::g_resolver_lookup_by_name_with_flags(
246 self.as_ref().to_glib_none().0,
247 hostname.to_glib_none().0,
248 flags.into_glib(),
249 cancellable.map(|p| p.as_ref()).to_glib_none().0,
250 &mut error,
251 );
252 if error.is_null() {
253 Ok(FromGlibPtrContainer::from_glib_full(ret))
254 } else {
255 Err(from_glib_full(error))
256 }
257 }
258 }
259
260 #[cfg(feature = "v2_60")]
261 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
262 #[doc(alias = "g_resolver_lookup_by_name_with_flags_async")]
263 fn lookup_by_name_with_flags_async<
264 P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
265 >(
266 &self,
267 hostname: &str,
268 flags: ResolverNameLookupFlags,
269 cancellable: Option<&impl IsA<Cancellable>>,
270 callback: P,
271 ) {
272 let main_context = glib::MainContext::ref_thread_default();
273 let is_main_context_owner = main_context.is_owner();
274 let has_acquired_main_context = (!is_main_context_owner)
275 .then(|| main_context.acquire().ok())
276 .flatten();
277 assert!(
278 is_main_context_owner || has_acquired_main_context.is_some(),
279 "Async operations only allowed if the thread is owning the MainContext"
280 );
281
282 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
283 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
284 unsafe extern "C" fn lookup_by_name_with_flags_async_trampoline<
285 P: FnOnce(Result<Vec<InetAddress>, glib::Error>) + 'static,
286 >(
287 _source_object: *mut glib::gobject_ffi::GObject,
288 res: *mut crate::ffi::GAsyncResult,
289 user_data: glib::ffi::gpointer,
290 ) {
291 let mut error = std::ptr::null_mut();
292 let ret = ffi::g_resolver_lookup_by_name_with_flags_finish(
293 _source_object as *mut _,
294 res,
295 &mut error,
296 );
297 let result = if error.is_null() {
298 Ok(FromGlibPtrContainer::from_glib_full(ret))
299 } else {
300 Err(from_glib_full(error))
301 };
302 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
303 Box_::from_raw(user_data as *mut _);
304 let callback: P = callback.into_inner();
305 callback(result);
306 }
307 let callback = lookup_by_name_with_flags_async_trampoline::<P>;
308 unsafe {
309 ffi::g_resolver_lookup_by_name_with_flags_async(
310 self.as_ref().to_glib_none().0,
311 hostname.to_glib_none().0,
312 flags.into_glib(),
313 cancellable.map(|p| p.as_ref()).to_glib_none().0,
314 Some(callback),
315 Box_::into_raw(user_data) as *mut _,
316 );
317 }
318 }
319
320 #[cfg(feature = "v2_60")]
321 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
322 fn lookup_by_name_with_flags_future(
323 &self,
324 hostname: &str,
325 flags: ResolverNameLookupFlags,
326 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<InetAddress>, glib::Error>> + 'static>>
327 {
328 let hostname = String::from(hostname);
329 Box_::pin(crate::GioFuture::new(
330 self,
331 move |obj, cancellable, send| {
332 obj.lookup_by_name_with_flags_async(
333 &hostname,
334 flags,
335 Some(cancellable),
336 move |res| {
337 send.resolve(res);
338 },
339 );
340 },
341 ))
342 }
343
344 #[doc(alias = "g_resolver_lookup_records")]
345 fn lookup_records(
346 &self,
347 rrname: &str,
348 record_type: ResolverRecordType,
349 cancellable: Option<&impl IsA<Cancellable>>,
350 ) -> Result<Vec<glib::Variant>, glib::Error> {
351 unsafe {
352 let mut error = std::ptr::null_mut();
353 let ret = ffi::g_resolver_lookup_records(
354 self.as_ref().to_glib_none().0,
355 rrname.to_glib_none().0,
356 record_type.into_glib(),
357 cancellable.map(|p| p.as_ref()).to_glib_none().0,
358 &mut error,
359 );
360 if error.is_null() {
361 Ok(FromGlibPtrContainer::from_glib_full(ret))
362 } else {
363 Err(from_glib_full(error))
364 }
365 }
366 }
367
368 #[doc(alias = "g_resolver_lookup_records_async")]
369 fn lookup_records_async<P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static>(
370 &self,
371 rrname: &str,
372 record_type: ResolverRecordType,
373 cancellable: Option<&impl IsA<Cancellable>>,
374 callback: P,
375 ) {
376 let main_context = glib::MainContext::ref_thread_default();
377 let is_main_context_owner = main_context.is_owner();
378 let has_acquired_main_context = (!is_main_context_owner)
379 .then(|| main_context.acquire().ok())
380 .flatten();
381 assert!(
382 is_main_context_owner || has_acquired_main_context.is_some(),
383 "Async operations only allowed if the thread is owning the MainContext"
384 );
385
386 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
387 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
388 unsafe extern "C" fn lookup_records_async_trampoline<
389 P: FnOnce(Result<Vec<glib::Variant>, glib::Error>) + 'static,
390 >(
391 _source_object: *mut glib::gobject_ffi::GObject,
392 res: *mut crate::ffi::GAsyncResult,
393 user_data: glib::ffi::gpointer,
394 ) {
395 let mut error = std::ptr::null_mut();
396 let ret =
397 ffi::g_resolver_lookup_records_finish(_source_object as *mut _, res, &mut error);
398 let result = if error.is_null() {
399 Ok(FromGlibPtrContainer::from_glib_full(ret))
400 } else {
401 Err(from_glib_full(error))
402 };
403 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
404 Box_::from_raw(user_data as *mut _);
405 let callback: P = callback.into_inner();
406 callback(result);
407 }
408 let callback = lookup_records_async_trampoline::<P>;
409 unsafe {
410 ffi::g_resolver_lookup_records_async(
411 self.as_ref().to_glib_none().0,
412 rrname.to_glib_none().0,
413 record_type.into_glib(),
414 cancellable.map(|p| p.as_ref()).to_glib_none().0,
415 Some(callback),
416 Box_::into_raw(user_data) as *mut _,
417 );
418 }
419 }
420
421 fn lookup_records_future(
422 &self,
423 rrname: &str,
424 record_type: ResolverRecordType,
425 ) -> Pin<
426 Box_<dyn std::future::Future<Output = Result<Vec<glib::Variant>, glib::Error>> + 'static>,
427 > {
428 let rrname = String::from(rrname);
429 Box_::pin(crate::GioFuture::new(
430 self,
431 move |obj, cancellable, send| {
432 obj.lookup_records_async(&rrname, record_type, Some(cancellable), move |res| {
433 send.resolve(res);
434 });
435 },
436 ))
437 }
438
439 #[doc(alias = "g_resolver_lookup_service")]
440 fn lookup_service(
441 &self,
442 service: &str,
443 protocol: &str,
444 domain: &str,
445 cancellable: Option<&impl IsA<Cancellable>>,
446 ) -> Result<Vec<SrvTarget>, glib::Error> {
447 unsafe {
448 let mut error = std::ptr::null_mut();
449 let ret = ffi::g_resolver_lookup_service(
450 self.as_ref().to_glib_none().0,
451 service.to_glib_none().0,
452 protocol.to_glib_none().0,
453 domain.to_glib_none().0,
454 cancellable.map(|p| p.as_ref()).to_glib_none().0,
455 &mut error,
456 );
457 if error.is_null() {
458 Ok(FromGlibPtrContainer::from_glib_full(ret))
459 } else {
460 Err(from_glib_full(error))
461 }
462 }
463 }
464
465 #[doc(alias = "g_resolver_lookup_service_async")]
466 fn lookup_service_async<P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static>(
467 &self,
468 service: &str,
469 protocol: &str,
470 domain: &str,
471 cancellable: Option<&impl IsA<Cancellable>>,
472 callback: P,
473 ) {
474 let main_context = glib::MainContext::ref_thread_default();
475 let is_main_context_owner = main_context.is_owner();
476 let has_acquired_main_context = (!is_main_context_owner)
477 .then(|| main_context.acquire().ok())
478 .flatten();
479 assert!(
480 is_main_context_owner || has_acquired_main_context.is_some(),
481 "Async operations only allowed if the thread is owning the MainContext"
482 );
483
484 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
485 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
486 unsafe extern "C" fn lookup_service_async_trampoline<
487 P: FnOnce(Result<Vec<SrvTarget>, glib::Error>) + 'static,
488 >(
489 _source_object: *mut glib::gobject_ffi::GObject,
490 res: *mut crate::ffi::GAsyncResult,
491 user_data: glib::ffi::gpointer,
492 ) {
493 let mut error = std::ptr::null_mut();
494 let ret =
495 ffi::g_resolver_lookup_service_finish(_source_object as *mut _, res, &mut error);
496 let result = if error.is_null() {
497 Ok(FromGlibPtrContainer::from_glib_full(ret))
498 } else {
499 Err(from_glib_full(error))
500 };
501 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
502 Box_::from_raw(user_data as *mut _);
503 let callback: P = callback.into_inner();
504 callback(result);
505 }
506 let callback = lookup_service_async_trampoline::<P>;
507 unsafe {
508 ffi::g_resolver_lookup_service_async(
509 self.as_ref().to_glib_none().0,
510 service.to_glib_none().0,
511 protocol.to_glib_none().0,
512 domain.to_glib_none().0,
513 cancellable.map(|p| p.as_ref()).to_glib_none().0,
514 Some(callback),
515 Box_::into_raw(user_data) as *mut _,
516 );
517 }
518 }
519
520 fn lookup_service_future(
521 &self,
522 service: &str,
523 protocol: &str,
524 domain: &str,
525 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Vec<SrvTarget>, glib::Error>> + 'static>>
526 {
527 let service = String::from(service);
528 let protocol = String::from(protocol);
529 let domain = String::from(domain);
530 Box_::pin(crate::GioFuture::new(
531 self,
532 move |obj, cancellable, send| {
533 obj.lookup_service_async(
534 &service,
535 &protocol,
536 &domain,
537 Some(cancellable),
538 move |res| {
539 send.resolve(res);
540 },
541 );
542 },
543 ))
544 }
545
546 #[doc(alias = "g_resolver_set_default")]
547 fn set_default(&self) {
548 unsafe {
549 ffi::g_resolver_set_default(self.as_ref().to_glib_none().0);
550 }
551 }
552
553 #[cfg(feature = "v2_78")]
554 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
555 #[doc(alias = "g_resolver_set_timeout")]
556 #[doc(alias = "timeout")]
557 fn set_timeout(&self, timeout_ms: u32) {
558 unsafe {
559 ffi::g_resolver_set_timeout(self.as_ref().to_glib_none().0, timeout_ms);
560 }
561 }
562
563 #[doc(alias = "reload")]
564 fn connect_reload<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
565 unsafe extern "C" fn reload_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
566 this: *mut ffi::GResolver,
567 f: glib::ffi::gpointer,
568 ) {
569 let f: &F = &*(f as *const F);
570 f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
571 }
572 unsafe {
573 let f: Box_<F> = Box_::new(f);
574 connect_raw(
575 self.as_ptr() as *mut _,
576 c"reload".as_ptr() as *const _,
577 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
578 reload_trampoline::<Self, F> as *const (),
579 )),
580 Box_::into_raw(f),
581 )
582 }
583 }
584
585 #[cfg(feature = "v2_78")]
586 #[cfg_attr(docsrs, doc(cfg(feature = "v2_78")))]
587 #[doc(alias = "timeout")]
588 fn connect_timeout_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
589 unsafe extern "C" fn notify_timeout_trampoline<P: IsA<Resolver>, F: Fn(&P) + 'static>(
590 this: *mut ffi::GResolver,
591 _param_spec: glib::ffi::gpointer,
592 f: glib::ffi::gpointer,
593 ) {
594 let f: &F = &*(f as *const F);
595 f(Resolver::from_glib_borrow(this).unsafe_cast_ref())
596 }
597 unsafe {
598 let f: Box_<F> = Box_::new(f);
599 connect_raw(
600 self.as_ptr() as *mut _,
601 c"notify::timeout".as_ptr() as *const _,
602 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
603 notify_timeout_trampoline::<Self, F> as *const (),
604 )),
605 Box_::into_raw(f),
606 )
607 }
608 }
609}
610
611impl<O: IsA<Resolver>> ResolverExt for O {}