use std::convert::{TryFrom, TryInto};
use zvariant::{OwnedValue, Value};
use crate::{Connection, Error, Message, Result};
use crate::fdo::{self, IntrospectableProxy, PropertiesProxy};
pub struct Proxy<'a> {
conn: &'a Connection,
destination: &'a str,
path: &'a str,
interface: &'a str,
}
impl<'a> Proxy<'a> {
pub fn new(
conn: &'a Connection,
destination: &'a str,
path: &'a str,
interface: &'a str,
) -> Result<Self> {
Ok(Self {
conn,
destination,
path,
interface,
})
}
pub fn introspect(&self) -> fdo::Result<String> {
IntrospectableProxy::new_for(self.conn, self.destination, self.path)?.introspect()
}
pub fn get_property<T>(&self, property_name: &str) -> fdo::Result<T>
where
T: TryFrom<OwnedValue>,
{
PropertiesProxy::new_for(self.conn, self.destination, self.path)?
.get(self.interface, property_name)?
.try_into()
.map_err(|_| Error::InvalidReply.into())
}
pub fn set_property<'t, T: 't>(&self, property_name: &str, value: T) -> fdo::Result<()>
where
T: Into<Value<'t>>,
{
PropertiesProxy::new_for(self.conn, self.destination, self.path)?.set(
self.interface,
property_name,
&value.into(),
)
}
pub fn call_method<B>(&self, method_name: &str, body: &B) -> Result<Message>
where
B: serde::ser::Serialize + zvariant::Type,
{
let reply = self.conn.call_method(
Some(self.destination),
self.path,
Some(self.interface),
method_name,
body,
);
match reply {
Ok(mut reply) => {
reply.disown_fds();
Ok(reply)
}
Err(e) => Err(e),
}
}
pub fn call<B, R>(&self, method_name: &str, body: &B) -> Result<R>
where
B: serde::ser::Serialize + zvariant::Type,
R: serde::de::DeserializeOwned + zvariant::Type,
{
Ok(self.call_method(method_name, body)?.body()?)
}
}