cranpose_services/
network_status.rs1use std::cell::RefCell;
9use std::rc::Rc;
10
11#[derive(Clone, Copy, PartialEq, Eq, Debug)]
13pub struct NetworkStatus {
14 pub online: bool,
16 pub metered: bool,
18}
19
20impl Default for NetworkStatus {
21 fn default() -> Self {
22 Self {
23 online: true,
24 metered: false,
25 }
26 }
27}
28
29pub trait NetworkMonitor {
31 fn status(&self) -> NetworkStatus;
32}
33
34pub type NetworkMonitorRef = Rc<dyn NetworkMonitor>;
35
36struct DefaultNetworkMonitor;
37
38impl NetworkMonitor for DefaultNetworkMonitor {
39 fn status(&self) -> NetworkStatus {
40 NetworkStatus::default()
41 }
42}
43
44thread_local! {
45 static PLATFORM_NETWORK_MONITOR: RefCell<Option<NetworkMonitorRef>> = const { RefCell::new(None) };
46}
47
48pub fn set_platform_network_monitor(monitor: NetworkMonitorRef) {
50 PLATFORM_NETWORK_MONITOR.with(|cell| *cell.borrow_mut() = Some(monitor));
51}
52
53pub fn clear_platform_network_monitor() {
55 PLATFORM_NETWORK_MONITOR.with(|cell| *cell.borrow_mut() = None);
56}
57
58pub fn network_monitor() -> NetworkMonitorRef {
61 PLATFORM_NETWORK_MONITOR
62 .with(|cell| cell.borrow().clone())
63 .unwrap_or_else(|| Rc::new(DefaultNetworkMonitor))
64}
65
66pub fn network_status() -> NetworkStatus {
68 network_monitor().status()
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn default_is_online_unmetered_and_overridable() {
77 clear_platform_network_monitor();
78 assert_eq!(
79 network_status(),
80 NetworkStatus {
81 online: true,
82 metered: false
83 }
84 );
85 struct Metered;
86 impl NetworkMonitor for Metered {
87 fn status(&self) -> NetworkStatus {
88 NetworkStatus {
89 online: true,
90 metered: true,
91 }
92 }
93 }
94 set_platform_network_monitor(Rc::new(Metered));
95 assert!(network_status().metered);
96 clear_platform_network_monitor();
97 }
98}