Add basic dbus proxy logic
This commit is contained in:
parent
f99ee75f98
commit
3f47840318
@ -1,4 +1,103 @@
|
||||
use log::{ debug, info, warn, error };
|
||||
use dbus::{
|
||||
nonblock::Proxy,
|
||||
Error
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
const DBUS_NAME: &'static str = "org.ddnss.sfs.mc";
|
||||
|
||||
fn iface_name(iface: &str) -> String {
|
||||
DBUS_NAME.to_owned() + "." + iface
|
||||
}
|
||||
|
||||
// #[non_exhaustive]
|
||||
pub enum NativeObject<'proxy> {
|
||||
Daemon(Proxy<'proxy, Arc<dbus::nonblock::SyncConnection>>),
|
||||
Minecraft(Proxy<'proxy, Arc<dbus::nonblock::SyncConnection>>),
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for NativeObject<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "NativeObject::").and(
|
||||
match self {
|
||||
Self::Daemon(_) => f.debug_tuple("Daemon"),
|
||||
Self::Minecraft(_) => f.debug_tuple("Minecraft")
|
||||
}.field(&"_").finish()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'proxy> NativeObject<'proxy> {
|
||||
pub fn new(c: Arc<dbus::nonblock::SyncConnection>, path: &'proxy str) -> Self {
|
||||
match path {
|
||||
"/" => Self::Daemon(Proxy::<'proxy>::new(DBUS_NAME, path, std::time::Duration::from_secs(5), c)),
|
||||
"/minecraft" => Self::Minecraft(Proxy::<'proxy>::new(DBUS_NAME, path, std::time::Duration::from_secs(5), c)),
|
||||
_ => panic!("Unknown object path {:?}", path)
|
||||
}
|
||||
}
|
||||
|
||||
fn no_path<MD: core::fmt::Display, VD: core::fmt::Debug>(method: MD, variant: VD) -> ! {
|
||||
panic!("No method {} on variant {:?}", method, variant)
|
||||
}
|
||||
|
||||
pub async fn start(&self) -> Result<(), Error> {
|
||||
let proxy = match self {
|
||||
Self::Daemon(p) | Self::Minecraft(p) => p,
|
||||
_ => Self::no_path("start", self)
|
||||
};
|
||||
|
||||
proxy.method_call(iface_name("Service"), "Start", ()).await
|
||||
}
|
||||
|
||||
pub async fn stop(&self) -> Result<(), Error> {
|
||||
let proxy = match self {
|
||||
Self::Daemon(p) | Self::Minecraft(p) => p,
|
||||
_ => Self::no_path("stop", self)
|
||||
};
|
||||
|
||||
let res = proxy.method_call(iface_name("Service"), "Stop", ()).await;
|
||||
res.or_else(|err|
|
||||
if
|
||||
proxy.path.to_string() == "/".to_owned() &&
|
||||
err.name() == Some("org.freedesktop.DBus.Error.NoReply") &&
|
||||
err.message() == Some("Message recipient disconnected from message bus without replying")
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn is_running(&self) -> bool {
|
||||
let proxy = match self {
|
||||
Self::Daemon(p) | Self::Minecraft(p) => p,
|
||||
_ => Self::no_path("is_running", self)
|
||||
};
|
||||
|
||||
let res = proxy.method_call(iface_name("Service"), "IsRunning", ()).await;
|
||||
res.map(|data: (bool,)| data.0).or_else(|err|
|
||||
if
|
||||
proxy.path.to_string() == "/".to_string() &&
|
||||
err.name() == Some("org.freedesktop.DBus.Error.ServiceUnknown")
|
||||
{
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
).unwrap()
|
||||
}
|
||||
|
||||
pub async fn restart(&self) -> Result<(), Error> {
|
||||
let proxy = match self {
|
||||
Self::Daemon(p) | Self::Minecraft(p) => p,
|
||||
_ => Self::no_path("restart", self)
|
||||
};
|
||||
|
||||
proxy.method_call(iface_name("Service"), "Restart", ()).await
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
@ -21,8 +120,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
panic!("Lost connection to D-Bus: {}", err);
|
||||
});
|
||||
|
||||
// Get a proxy connection to the daemon
|
||||
let daemon = NativeObject::new(c, "/");
|
||||
|
||||
// TODO:
|
||||
// Perform operations
|
||||
info!("The daemon is{} running", if !daemon.is_running().await {"n't"} else {""});
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user