1use crate::{ffi, AsyncResult, Cancellable, Initable, NetworkConnectivity, SocketConnectable};
6use glib::{
7 object::ObjectType as _,
8 prelude::*,
9 signal::{connect_raw, SignalHandlerId},
10 translate::*,
11};
12use std::{boxed::Box as Box_, pin::Pin};
13
14glib::wrapper! {
15 #[doc(alias = "GNetworkMonitor")]
16 pub struct NetworkMonitor(Interface<ffi::GNetworkMonitor, ffi::GNetworkMonitorInterface>) @requires Initable;
17
18 match fn {
19 type_ => || ffi::g_network_monitor_get_type(),
20 }
21}
22
23impl NetworkMonitor {
24 pub const NONE: Option<&'static NetworkMonitor> = None;
25
26 #[doc(alias = "g_network_monitor_get_default")]
27 #[doc(alias = "get_default")]
28 #[allow(clippy::should_implement_trait)]
29 pub fn default() -> NetworkMonitor {
30 unsafe { from_glib_none(ffi::g_network_monitor_get_default()) }
31 }
32}
33
34pub trait NetworkMonitorExt: IsA<NetworkMonitor> + 'static {
35 #[doc(alias = "g_network_monitor_can_reach")]
36 fn can_reach(
37 &self,
38 connectable: &impl IsA<SocketConnectable>,
39 cancellable: Option<&impl IsA<Cancellable>>,
40 ) -> Result<(), glib::Error> {
41 unsafe {
42 let mut error = std::ptr::null_mut();
43 let is_ok = ffi::g_network_monitor_can_reach(
44 self.as_ref().to_glib_none().0,
45 connectable.as_ref().to_glib_none().0,
46 cancellable.map(|p| p.as_ref()).to_glib_none().0,
47 &mut error,
48 );
49 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
50 if error.is_null() {
51 Ok(())
52 } else {
53 Err(from_glib_full(error))
54 }
55 }
56 }
57
58 #[doc(alias = "g_network_monitor_can_reach_async")]
59 fn can_reach_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
60 &self,
61 connectable: &impl IsA<SocketConnectable>,
62 cancellable: Option<&impl IsA<Cancellable>>,
63 callback: P,
64 ) {
65 let main_context = glib::MainContext::ref_thread_default();
66 let is_main_context_owner = main_context.is_owner();
67 let has_acquired_main_context = (!is_main_context_owner)
68 .then(|| main_context.acquire().ok())
69 .flatten();
70 assert!(
71 is_main_context_owner || has_acquired_main_context.is_some(),
72 "Async operations only allowed if the thread is owning the MainContext"
73 );
74
75 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
76 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
77 unsafe extern "C" fn can_reach_async_trampoline<
78 P: FnOnce(Result<(), glib::Error>) + 'static,
79 >(
80 _source_object: *mut glib::gobject_ffi::GObject,
81 res: *mut crate::ffi::GAsyncResult,
82 user_data: glib::ffi::gpointer,
83 ) {
84 let mut error = std::ptr::null_mut();
85 ffi::g_network_monitor_can_reach_finish(_source_object as *mut _, res, &mut error);
86 let result = if error.is_null() {
87 Ok(())
88 } else {
89 Err(from_glib_full(error))
90 };
91 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
92 Box_::from_raw(user_data as *mut _);
93 let callback: P = callback.into_inner();
94 callback(result);
95 }
96 let callback = can_reach_async_trampoline::<P>;
97 unsafe {
98 ffi::g_network_monitor_can_reach_async(
99 self.as_ref().to_glib_none().0,
100 connectable.as_ref().to_glib_none().0,
101 cancellable.map(|p| p.as_ref()).to_glib_none().0,
102 Some(callback),
103 Box_::into_raw(user_data) as *mut _,
104 );
105 }
106 }
107
108 fn can_reach_future(
109 &self,
110 connectable: &(impl IsA<SocketConnectable> + Clone + 'static),
111 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
112 let connectable = connectable.clone();
113 Box_::pin(crate::GioFuture::new(
114 self,
115 move |obj, cancellable, send| {
116 obj.can_reach_async(&connectable, Some(cancellable), move |res| {
117 send.resolve(res);
118 });
119 },
120 ))
121 }
122
123 #[doc(alias = "g_network_monitor_get_connectivity")]
124 #[doc(alias = "get_connectivity")]
125 fn connectivity(&self) -> NetworkConnectivity {
126 unsafe {
127 from_glib(ffi::g_network_monitor_get_connectivity(
128 self.as_ref().to_glib_none().0,
129 ))
130 }
131 }
132
133 #[doc(alias = "g_network_monitor_get_network_available")]
134 #[doc(alias = "get_network_available")]
135 #[doc(alias = "network-available")]
136 fn is_network_available(&self) -> bool {
137 unsafe {
138 from_glib(ffi::g_network_monitor_get_network_available(
139 self.as_ref().to_glib_none().0,
140 ))
141 }
142 }
143
144 #[doc(alias = "g_network_monitor_get_network_metered")]
145 #[doc(alias = "get_network_metered")]
146 #[doc(alias = "network-metered")]
147 fn is_network_metered(&self) -> bool {
148 unsafe {
149 from_glib(ffi::g_network_monitor_get_network_metered(
150 self.as_ref().to_glib_none().0,
151 ))
152 }
153 }
154
155 #[doc(alias = "network-changed")]
156 fn connect_network_changed<F: Fn(&Self, bool) + 'static>(&self, f: F) -> SignalHandlerId {
157 unsafe extern "C" fn network_changed_trampoline<
158 P: IsA<NetworkMonitor>,
159 F: Fn(&P, bool) + 'static,
160 >(
161 this: *mut ffi::GNetworkMonitor,
162 network_available: glib::ffi::gboolean,
163 f: glib::ffi::gpointer,
164 ) {
165 let f: &F = &*(f as *const F);
166 f(
167 NetworkMonitor::from_glib_borrow(this).unsafe_cast_ref(),
168 from_glib(network_available),
169 )
170 }
171 unsafe {
172 let f: Box_<F> = Box_::new(f);
173 connect_raw(
174 self.as_ptr() as *mut _,
175 c"network-changed".as_ptr() as *const _,
176 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
177 network_changed_trampoline::<Self, F> as *const (),
178 )),
179 Box_::into_raw(f),
180 )
181 }
182 }
183
184 #[doc(alias = "connectivity")]
185 fn connect_connectivity_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
186 unsafe extern "C" fn notify_connectivity_trampoline<
187 P: IsA<NetworkMonitor>,
188 F: Fn(&P) + 'static,
189 >(
190 this: *mut ffi::GNetworkMonitor,
191 _param_spec: glib::ffi::gpointer,
192 f: glib::ffi::gpointer,
193 ) {
194 let f: &F = &*(f as *const F);
195 f(NetworkMonitor::from_glib_borrow(this).unsafe_cast_ref())
196 }
197 unsafe {
198 let f: Box_<F> = Box_::new(f);
199 connect_raw(
200 self.as_ptr() as *mut _,
201 c"notify::connectivity".as_ptr() as *const _,
202 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
203 notify_connectivity_trampoline::<Self, F> as *const (),
204 )),
205 Box_::into_raw(f),
206 )
207 }
208 }
209
210 #[doc(alias = "network-available")]
211 fn connect_network_available_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
212 unsafe extern "C" fn notify_network_available_trampoline<
213 P: IsA<NetworkMonitor>,
214 F: Fn(&P) + 'static,
215 >(
216 this: *mut ffi::GNetworkMonitor,
217 _param_spec: glib::ffi::gpointer,
218 f: glib::ffi::gpointer,
219 ) {
220 let f: &F = &*(f as *const F);
221 f(NetworkMonitor::from_glib_borrow(this).unsafe_cast_ref())
222 }
223 unsafe {
224 let f: Box_<F> = Box_::new(f);
225 connect_raw(
226 self.as_ptr() as *mut _,
227 c"notify::network-available".as_ptr() as *const _,
228 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
229 notify_network_available_trampoline::<Self, F> as *const (),
230 )),
231 Box_::into_raw(f),
232 )
233 }
234 }
235
236 #[doc(alias = "network-metered")]
237 fn connect_network_metered_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
238 unsafe extern "C" fn notify_network_metered_trampoline<
239 P: IsA<NetworkMonitor>,
240 F: Fn(&P) + 'static,
241 >(
242 this: *mut ffi::GNetworkMonitor,
243 _param_spec: glib::ffi::gpointer,
244 f: glib::ffi::gpointer,
245 ) {
246 let f: &F = &*(f as *const F);
247 f(NetworkMonitor::from_glib_borrow(this).unsafe_cast_ref())
248 }
249 unsafe {
250 let f: Box_<F> = Box_::new(f);
251 connect_raw(
252 self.as_ptr() as *mut _,
253 c"notify::network-metered".as_ptr() as *const _,
254 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
255 notify_network_metered_trampoline::<Self, F> as *const (),
256 )),
257 Box_::into_raw(f),
258 )
259 }
260 }
261}
262
263impl<O: IsA<NetworkMonitor>> NetworkMonitorExt for O {}