Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add versioned methods #163

Merged
merged 2 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/desktop/background.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ impl<'a> BackgroundProxy<'a> {

pub async fn set_status(&self, message: &str) -> Result<(), Error> {
self.0
.call(
.call_versioned(
"SetStatus",
&(SetStatusOptions {
message: message.to_owned(),
}),
2,
)
.await
}
Expand Down
12 changes: 7 additions & 5 deletions src/desktop/network_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ impl<'a> NetworkMonitor<'a> {
/// See also [`CanReach`](https://flatpak.github.io/xdg-desktop-portal/index.html#gdbus-method-org-freedesktop-portal-NetworkMonitor.CanReach).
#[doc(alias = "CanReach")]
pub async fn can_reach(&self, hostname: &str, port: u32) -> Result<bool, Error> {
self.0.call("CanReach", &(hostname, port)).await
self.0
.call_versioned("CanReach", &(hostname, port), 3)
.await
}

/// Returns whether the network is considered available.
Expand All @@ -123,7 +125,7 @@ impl<'a> NetworkMonitor<'a> {
#[doc(alias = "GetAvailable")]
#[doc(alias = "get_available")]
pub async fn is_available(&self) -> Result<bool, Error> {
self.0.call("GetAvailable", &()).await
self.0.call_versioned("GetAvailable", &(), 2).await
}

/// Returns more detailed information about the host's network connectivity.
Expand All @@ -134,7 +136,7 @@ impl<'a> NetworkMonitor<'a> {
#[doc(alias = "GetConnectivity")]
#[doc(alias = "get_connectivity")]
pub async fn connectivity(&self) -> Result<Connectivity, Error> {
self.0.call("GetConnectivity", &()).await
self.0.call_versioned("GetConnectivity", &(), 2).await
}

/// Returns whether the network is considered metered.
Expand All @@ -147,7 +149,7 @@ impl<'a> NetworkMonitor<'a> {
#[doc(alias = "GetMetered")]
#[doc(alias = "get_metered")]
pub async fn is_metered(&self) -> Result<bool, Error> {
self.0.call("GetMetered", &()).await
self.0.call_versioned("GetMetered", &(), 2).await
}

/// Returns the three values all at once.
Expand All @@ -158,7 +160,7 @@ impl<'a> NetworkMonitor<'a> {
#[doc(alias = "GetStatus")]
#[doc(alias = "get_status")]
pub async fn status(&self) -> Result<NetworkStatus, Error> {
self.0.call("GetStatus", &()).await
self.0.call_versioned("GetStatus", &(), 3).await
}

/// Emitted when the network configuration changes.
Expand Down
2 changes: 1 addition & 1 deletion src/desktop/remote_desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ impl<'a> RemoteDesktop<'a> {
let options: HashMap<&str, Value<'_>> = HashMap::new();
let fd = self
.0
.call::<OwnedFd>("ConnectToEIS", &(session, options))
.call_versioned::<OwnedFd>("ConnectToEIS", &(session, options), 2)
.await?;
Ok(fd.into_raw_fd())
}
Expand Down
2 changes: 1 addition & 1 deletion src/desktop/screencast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ impl<'a> Screencast<'a> {
/// See also [`AvailableCursorModes`](https://flatpak.github.io/xdg-desktop-portal/index.html#gdbus-property-org-freedesktop-portal-ScreenCast.AvailableCursorModes).
#[doc(alias = "AvailableCursorModes")]
pub async fn available_cursor_modes(&self) -> Result<BitFlags<CursorMode>, Error> {
self.0.property("AvailableCursorModes").await
self.0.property_versioned("AvailableCursorModes", 2).await
}

/// Available source types.
Expand Down
5 changes: 3 additions & 2 deletions src/documents/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl<'a> Documents<'a> {
let o_path: Vec<Fd> = o_path_fds.iter().map(|f| Fd::from(f.as_raw_fd())).collect();
let app_id = app_id.as_deref().unwrap_or("");
self.0
.call("AddFull", &(o_path, flags, app_id, permissions))
.call_versioned("AddFull", &(o_path, flags, app_id, permissions), 2)
.await
}

Expand Down Expand Up @@ -295,7 +295,7 @@ impl<'a> Documents<'a> {
let app_id = app_id.as_deref().unwrap_or("");
let filename = FilePath::new(filename)?;
self.0
.call(
.call_versioned(
"AddNamedFull",
&(
Fd::from(o_path_fd.as_raw_fd()),
Expand All @@ -304,6 +304,7 @@ impl<'a> Documents<'a> {
app_id,
permissions,
),
3,
)
.await
}
Expand Down
8 changes: 8 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
InvalidAppID,
/// An error indicating that an interior nul byte was found
NulTerminated(usize),
/// Requires a newer interface version.
///
/// The inner fields are the required version and the version advertised by
/// the interface.
RequiresVersion(u32, u32),
/// An error indicating that a Icon::Bytes was expected but wrong type was
/// passed
UnexpectedIcon,
Expand All @@ -73,6 +78,9 @@
Self::ParseError(e) => f.write_str(e),
Self::InvalidAppID => f.write_str("Invalid app id"),
Self::NulTerminated(u) => write!(f, "Nul byte found in provided data at position {u}"),
Self::RequiresVersion(required, current) => write!(

Check failure on line 81 in src/error.rs

View workflow job for this annotation

GitHub Actions / Clippy

mismatched closing delimiter: `}`

Check failure on line 81 in src/error.rs

View workflow job for this annotation

GitHub Actions / Check

mismatched closing delimiter: `}`

Check failure on line 81 in src/error.rs

View workflow job for this annotation

GitHub Actions / Rustfmt

mismatched closing delimiter: `}`

Check failure on line 81 in src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite

mismatched closing delimiter: `}`
f,
"This interface requires version {required}, but {current} is available"
Self::UnexpectedIcon => write!(
f,
"Expected icon of type Icon::Bytes but a different type was used."
Expand Down
6 changes: 4 additions & 2 deletions src/flatpak/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl<'a> Flatpak<'a> {
let options = CreateMonitorOptions::default();
let path = self
.0
.call::<OwnedObjectPath>("CreateUpdateMonitor", &(options))
.call_versioned::<OwnedObjectPath>("CreateUpdateMonitor", &(options), 2)
.await?;

UpdateMonitor::new(path.into_inner()).await
Expand Down Expand Up @@ -362,7 +362,9 @@ impl<'a> Flatpak<'a> {
///
/// See also [`supports`](https://flatpak.github.io/xdg-desktop-portal/index.html#gdbus-property-org-freedesktop-portal-Flatpak.supports).
pub async fn supports(&self) -> Result<BitFlags<SupportsFlags>, Error> {
self.0.property::<BitFlags<SupportsFlags>>("supports").await
self.0
.property_versioned::<BitFlags<SupportsFlags>>("supports", 3)
.await
}
}

Expand Down
58 changes: 51 additions & 7 deletions src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ pub(crate) const FLATPAK_PATH: &str = "/org/freedesktop/portal/Flatpak";
static SESSION: OnceCell<zbus::Connection> = OnceCell::new();

#[derive(Debug)]
pub struct Proxy<'a>(zbus::Proxy<'a>);
pub struct Proxy<'a> {
inner: zbus::Proxy<'a>,
version: u32,
}

impl<'a> Proxy<'a> {
pub(crate) async fn connection() -> zbus::Result<zbus::Connection> {
Expand Down Expand Up @@ -58,13 +61,15 @@ impl<'a> Proxy<'a> {
P::Error: Into<zbus::Error>,
{
let connection = Self::connection().await?;
let proxy = zbus::ProxyBuilder::new_bare(&connection)
let inner: zbus::Proxy = zbus::ProxyBuilder::new_bare(&connection)
.interface(interface)?
.path(path)?
.destination(destination)?
.build()
.await?;
Ok(Self(proxy))
let version = inner.get_property::<u32>("version").await.unwrap_or(1);

Ok(Self { inner, version })
}

pub async fn new_desktop_with_path<P>(interface: &'a str, path: P) -> Result<Proxy<'a>, Error>
Expand Down Expand Up @@ -122,6 +127,11 @@ impl<'a> Proxy<'a> {
self.request(handle_token, method_name, body).await
}

/// Returns the version of the interface
pub fn version(&self) -> u32 {
self.version
}

pub(crate) async fn call<R>(
&self,
method_name: &'static str,
Expand All @@ -145,17 +155,51 @@ impl<'a> Proxy<'a> {
Ok(reply)
}

pub(crate) async fn call_versioned<R>(
&self,
method_name: &'static str,
body: impl Serialize + Type + Debug,
req_version: u32,
) -> Result<R, Error>
where
R: for<'de> Deserialize<'de> + Type,
{
let version = self.version();
if version >= req_version {
self.call::<R>(method_name, body).await
} else {
Err(Error::RequiresVersion(req_version, version))
}
}

pub async fn property<T>(&self, property_name: &'static str) -> Result<T, Error>
where
T: TryFrom<OwnedValue>,
zbus::Error: From<<T as TryFrom<OwnedValue>>::Error>,
{
self.0
self.inner
.get_property::<T>(property_name)
.await
.map_err(From::from)
}

pub(crate) async fn property_versioned<T>(
&self,
property_name: &'static str,
req_version: u32,
) -> Result<T, Error>
where
T: TryFrom<OwnedValue>,
zbus::Error: From<<T as TryFrom<OwnedValue>>::Error>,
{
let version = self.version();
if version >= req_version {
self.property::<T>(property_name).await
} else {
Err(Error::RequiresVersion(req_version, version))
}
}

pub(crate) async fn signal_with_args<I>(
&self,
name: &'static str,
Expand All @@ -165,7 +209,7 @@ impl<'a> Proxy<'a> {
I: for<'de> Deserialize<'de> + Type + Debug,
{
Ok(self
.0
.inner
.receive_signal_with_args(name, args)
.await?
.filter_map({
Expand All @@ -185,7 +229,7 @@ impl<'a> Proxy<'a> {
where
I: for<'de> Deserialize<'de> + Type + Debug,
{
Ok(self.0.receive_signal(name).await?.filter_map({
Ok(self.inner.receive_signal(name).await?.filter_map({
#[cfg(not(feature = "tracing"))]
{
move |msg| ready(msg.body().ok())
Expand Down Expand Up @@ -221,6 +265,6 @@ impl<'a> Deref for Proxy<'a> {
type Target = zbus::Proxy<'a>;

fn deref(&self) -> &Self::Target {
&self.0
&self.inner
}
}
Loading