A src/filechooser.rs => src/filechooser.rs +38 -0
@@ 0,0 1,38 @@
+use std::collections::HashMap;
+use std::error::Error;
+
+use zbus::{blocking::Connection, dbus_proxy, zvariant};
+
+#[dbus_proxy(
+ default_service = "org.freedesktop.portal.Desktop",
+ default_path = "/org/freedesktop/portal/desktop",
+ interface = "org.freedesktop.portal.FileChooser"
+)]
+trait FileChooser {
+ fn open_file(
+ &self,
+ parent_window: &str,
+ title: &str,
+ options: HashMap<&str, &zvariant::Value<'_>>,
+ ) -> zbus::Result<zvariant::OwnedObjectPath>;
+}
+
+pub fn call(conn: &Connection, argument: Option<&str>) {
+ FileChooserProxyBlocking::new(conn)
+ .unwrap()
+ .open_file(
+ "",
+ argument.unwrap_or_default(),
+ HashMap::from([("multiple", &zvariant::Value::Bool(true))]),
+ )
+ .unwrap();
+}
+
+pub fn handle_reply(mut body: HashMap<String, zvariant::Value<'_>>) -> Result<(), Box<dyn Error>> {
+ let results: Vec<String> = body.remove("uris").unwrap().try_into()?;
+ results
+ .iter()
+ .map(|uri| uri.trim_start_matches("file://"))
+ .for_each(|uri| println!("{}", uri));
+ Ok(())
+}
M src/main.rs => src/main.rs +4 -108
@@ 1,9 1,12 @@
+mod filechooser;
+mod openuri;
+
use std::collections::HashMap;
use std::error::Error;
use zbus::{
blocking::{Connection, Proxy},
- dbus_proxy, zvariant,
+ zvariant,
};
static mut REQUEST: Option<Proxy> = None;
@@ 74,110 77,3 @@ fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}
-
-mod openuri {
- use super::*;
-
- use std::fs::File;
- use std::os::fd::AsRawFd;
-
- #[dbus_proxy(
- default_service = "org.freedesktop.portal.Desktop",
- default_path = "/org/freedesktop/portal/desktop",
- interface = "org.freedesktop.portal.OpenURI"
- )]
- trait OpenURI {
- #[dbus_proxy(name = "OpenURI")]
- fn open_uri(
- &self,
- parent_win: &str,
- uri: &str,
- options: HashMap<&str, &zvariant::Value<'_>>,
- ) -> zbus::Result<zvariant::OwnedObjectPath>;
-
- #[dbus_proxy(name = "OpenFile")]
- fn open_file(
- &self,
- parent_win: &str,
- fd: zvariant::Fd,
- options: HashMap<&str, &zvariant::Value<'_>>,
- ) -> zbus::Result<zvariant::OwnedObjectPath>;
-
- #[dbus_proxy(name = "OpenFile")]
- fn open_directory(
- &self,
- parent_win: &str,
- fd: zvariant::Fd,
- options: HashMap<&str, &zvariant::Value<'_>>,
- ) -> zbus::Result<zvariant::OwnedObjectPath>;
- }
-
- pub fn call(conn: &Connection, argument: Option<&str>) {
- let proxy = OpenURIProxyBlocking::new(conn).unwrap();
- let options = HashMap::from([("ask", &zvariant::Value::Bool(true))]);
-
- if let Some(a) = argument {
- let m = a.match_indices("://").next();
-
- // NOTE: support passing local file uris without schema
- if m.is_none() || a.get(..(m.unwrap().0)) == Some("file") {
- if let Ok(fd) = File::open(a.trim_start_matches("file://")) {
- let meta = fd.metadata();
- if meta.is_ok() && meta.unwrap().is_dir() {
- proxy
- .open_directory("", fd.as_raw_fd().into(), options)
- .unwrap();
- } else {
- proxy.open_file("", fd.as_raw_fd().into(), options).unwrap();
- }
- }
- } else {
- proxy.open_uri("", a, options).unwrap();
- }
- }
- }
-
- pub fn handle_reply(_body: HashMap<String, zvariant::Value<'_>>) -> Result<(), Box<dyn Error>> {
- Ok(())
- }
-}
-
-mod filechooser {
- use super::*;
-
- #[dbus_proxy(
- default_service = "org.freedesktop.portal.Desktop",
- default_path = "/org/freedesktop/portal/desktop",
- interface = "org.freedesktop.portal.FileChooser"
- )]
- trait FileChooser {
- fn open_file(
- &self,
- parent_window: &str,
- title: &str,
- options: HashMap<&str, &zvariant::Value<'_>>,
- ) -> zbus::Result<zvariant::OwnedObjectPath>;
- }
-
- pub fn call(conn: &Connection, argument: Option<&str>) {
- FileChooserProxyBlocking::new(conn)
- .unwrap()
- .open_file(
- "",
- argument.unwrap_or_default(),
- HashMap::from([("multiple", &zvariant::Value::Bool(true))]),
- )
- .unwrap();
- }
-
- pub fn handle_reply(
- mut body: HashMap<String, zvariant::Value<'_>>,
- ) -> Result<(), Box<dyn Error>> {
- let results: Vec<String> = body.remove("uris").unwrap().try_into()?;
- results
- .iter()
- .map(|uri| uri.trim_start_matches("file://"))
- .for_each(|uri| println!("{}", uri));
- Ok(())
- }
-}
A src/openuri.rs => src/openuri.rs +66 -0
@@ 0,0 1,66 @@
+use std::collections::HashMap;
+use std::error::Error;
+use std::fs::File;
+use std::os::fd::AsRawFd;
+
+use zbus::{blocking::Connection, dbus_proxy, zvariant};
+
+#[dbus_proxy(
+ default_service = "org.freedesktop.portal.Desktop",
+ default_path = "/org/freedesktop/portal/desktop",
+ interface = "org.freedesktop.portal.OpenURI"
+)]
+trait OpenURI {
+ #[dbus_proxy(name = "OpenURI")]
+ fn open_uri(
+ &self,
+ parent_win: &str,
+ uri: &str,
+ options: HashMap<&str, &zvariant::Value<'_>>,
+ ) -> zbus::Result<zvariant::OwnedObjectPath>;
+
+ #[dbus_proxy(name = "OpenFile")]
+ fn open_file(
+ &self,
+ parent_win: &str,
+ fd: zvariant::Fd,
+ options: HashMap<&str, &zvariant::Value<'_>>,
+ ) -> zbus::Result<zvariant::OwnedObjectPath>;
+
+ #[dbus_proxy(name = "OpenFile")]
+ fn open_directory(
+ &self,
+ parent_win: &str,
+ fd: zvariant::Fd,
+ options: HashMap<&str, &zvariant::Value<'_>>,
+ ) -> zbus::Result<zvariant::OwnedObjectPath>;
+}
+
+pub fn call(conn: &Connection, argument: Option<&str>) {
+ let proxy = OpenURIProxyBlocking::new(conn).unwrap();
+ let options = HashMap::from([("ask", &zvariant::Value::Bool(true))]);
+
+ if let Some(a) = argument {
+ let m = a.match_indices("://").next();
+
+ // NOTE: support passing local file uris without schema
+ if m.is_none() || a.get(..(m.unwrap().0)) == Some("file") {
+ if let Ok(fd) = File::open(a.trim_start_matches("file://")) {
+ let meta = fd.metadata();
+ if meta.is_ok() && meta.unwrap().is_dir() {
+ proxy
+ .open_directory("", fd.as_raw_fd().into(), options)
+ .unwrap();
+ } else {
+ proxy.open_file("", fd.as_raw_fd().into(), options).unwrap();
+ }
+ }
+ } else {
+ proxy.open_uri("", a, options).unwrap();
+ }
+ }
+}
+
+pub fn handle_reply(_body: HashMap<String, zvariant::Value<'_>>) -> Result<(), Box<dyn Error>> {
+ Ok(())
+}