gio/
dbus.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::num::NonZeroU32;
4
5use glib::translate::*;
6
7use crate::{ffi, BusNameOwnerFlags, BusNameWatcherFlags, BusType, DBusConnection};
8
9#[derive(Debug, Eq, PartialEq)]
10pub struct OwnerId(NonZeroU32);
11#[derive(Debug, Eq, PartialEq)]
12pub struct WatcherId(NonZeroU32);
13
14fn own_closure<F>(f: F) -> glib::Closure
15where
16    F: Fn(DBusConnection, &str) + 'static,
17{
18    glib::Closure::new_local(move |args| {
19        let conn = args[0].get::<DBusConnection>().unwrap();
20        let name = args[1].get::<&str>().unwrap();
21        f(conn, name);
22        None
23    })
24}
25
26fn appeared_closure<F>(f: F) -> glib::Closure
27where
28    F: Fn(DBusConnection, &str, &str) + 'static,
29{
30    glib::Closure::new_local(move |args| {
31        let conn = args[0].get::<DBusConnection>().unwrap();
32        let name = args[1].get::<&str>().unwrap();
33        let name_owner = args[2].get::<&str>().unwrap();
34        f(conn, name, name_owner);
35        None
36    })
37}
38
39fn vanished_closure<F>(f: F) -> glib::Closure
40where
41    F: Fn(DBusConnection, &str) + 'static,
42{
43    glib::Closure::new_local(move |args| {
44        let conn = args[0].get::<DBusConnection>().unwrap();
45        let name = args[1].get::<&str>().unwrap();
46        f(conn, name);
47        None
48    })
49}
50
51#[doc(alias = "g_bus_own_name_on_connection_with_closures")]
52pub fn bus_own_name_on_connection<NameAcquired, NameLost>(
53    connection: &DBusConnection,
54    name: &str,
55    flags: BusNameOwnerFlags,
56    name_acquired: NameAcquired,
57    name_lost: NameLost,
58) -> OwnerId
59where
60    NameAcquired: Fn(DBusConnection, &str) + 'static,
61    NameLost: Fn(DBusConnection, &str) + 'static,
62{
63    unsafe {
64        let id = ffi::g_bus_own_name_on_connection_with_closures(
65            connection.to_glib_none().0,
66            name.to_glib_none().0,
67            flags.into_glib(),
68            own_closure(name_acquired).to_glib_none().0,
69            own_closure(name_lost).to_glib_none().0,
70        );
71        OwnerId(NonZeroU32::new_unchecked(id))
72    }
73}
74
75#[doc(alias = "g_bus_own_name_with_closures")]
76pub fn bus_own_name<BusAcquired, NameAcquired, NameLost>(
77    bus_type: BusType,
78    name: &str,
79    flags: BusNameOwnerFlags,
80    bus_acquired: BusAcquired,
81    name_acquired: NameAcquired,
82    name_lost: NameLost,
83) -> OwnerId
84where
85    BusAcquired: Fn(DBusConnection, &str) + 'static,
86    NameAcquired: Fn(DBusConnection, &str) + 'static,
87    NameLost: Fn(Option<DBusConnection>, &str) + 'static,
88{
89    unsafe {
90        let id = ffi::g_bus_own_name_with_closures(
91            bus_type.into_glib(),
92            name.to_glib_none().0,
93            flags.into_glib(),
94            own_closure(bus_acquired).to_glib_none().0,
95            own_closure(name_acquired).to_glib_none().0,
96            glib::Closure::new_local(move |args| {
97                let conn = args[0].get::<Option<DBusConnection>>().unwrap();
98                let name = args[1].get::<&str>().unwrap();
99                name_lost(conn, name);
100                None
101            })
102            .to_glib_none()
103            .0,
104        );
105        OwnerId(NonZeroU32::new_unchecked(id))
106    }
107}
108
109#[doc(alias = "g_bus_unown_name")]
110pub fn bus_unown_name(owner_id: OwnerId) {
111    unsafe {
112        ffi::g_bus_unown_name(owner_id.0.into());
113    }
114}
115
116#[doc(alias = "g_bus_watch_name_on_connection_with_closures")]
117pub fn bus_watch_name_on_connection<NameAppeared, NameVanished>(
118    connection: &DBusConnection,
119    name: &str,
120    flags: BusNameWatcherFlags,
121    name_appeared: NameAppeared,
122    name_vanished: NameVanished,
123) -> WatcherId
124where
125    NameAppeared: Fn(DBusConnection, &str, &str) + 'static,
126    NameVanished: Fn(DBusConnection, &str) + 'static,
127{
128    unsafe {
129        let id = ffi::g_bus_watch_name_on_connection_with_closures(
130            connection.to_glib_none().0,
131            name.to_glib_none().0,
132            flags.into_glib(),
133            appeared_closure(name_appeared).to_glib_none().0,
134            vanished_closure(name_vanished).to_glib_none().0,
135        );
136        WatcherId(NonZeroU32::new_unchecked(id))
137    }
138}
139
140#[doc(alias = "g_bus_watch_name_with_closures")]
141pub fn bus_watch_name<NameAppeared, NameVanished>(
142    bus_type: BusType,
143    name: &str,
144    flags: BusNameWatcherFlags,
145    name_appeared: NameAppeared,
146    name_vanished: NameVanished,
147) -> WatcherId
148where
149    NameAppeared: Fn(DBusConnection, &str, &str) + 'static,
150    NameVanished: Fn(DBusConnection, &str) + 'static,
151{
152    unsafe {
153        let id = ffi::g_bus_watch_name_with_closures(
154            bus_type.into_glib(),
155            name.to_glib_none().0,
156            flags.into_glib(),
157            appeared_closure(name_appeared).to_glib_none().0,
158            vanished_closure(name_vanished).to_glib_none().0,
159        );
160        WatcherId(NonZeroU32::new_unchecked(id))
161    }
162}
163
164#[doc(alias = "g_bus_unwatch_name")]
165pub fn bus_unwatch_name(watcher_id: WatcherId) {
166    unsafe {
167        ffi::g_bus_unwatch_name(watcher_id.0.into());
168    }
169}