~robertgzr/porta

11a6e6c534c450943c2ce66d808c54888b350b5d — Robert Günzler 8 months ago a733f28
move portal modules into separate files

Signed-off-by: Robert Günzler <r@gnzler.io>
3 files changed, 108 insertions(+), 108 deletions(-)

A src/filechooser.rs
M src/main.rs
A src/openuri.rs
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(())
}