use std::{collections::HashMap, os::unix::prelude::AsRawFd};
use zbus::zvariant::{DeserializeDict, Fd, SerializeDict, Type, Value};
use super::{DESTINATION, PATH};
use crate::{
helpers::{call_method, receive_signal},
Error,
};
#[derive(SerializeDict, DeserializeDict, Debug, Type, Default)]
#[zvariant(signature = "dict")]
struct TransferOptions {
writeable: Option<bool>,
#[zvariant(rename = "autostop")]
auto_stop: Option<bool>,
}
impl TransferOptions {
#[must_use]
pub fn writeable(mut self, writeable: bool) -> Self {
self.writeable = Some(writeable);
self
}
#[must_use]
pub fn auto_stop(mut self, auto_stop: bool) -> Self {
self.auto_stop = Some(auto_stop);
self
}
}
#[derive(Debug)]
#[doc(alias = "org.freedesktop.portal.FileTransfer")]
pub struct FileTransferProxy<'a>(zbus::Proxy<'a>);
impl<'a> FileTransferProxy<'a> {
pub async fn new(connection: &zbus::Connection) -> Result<FileTransferProxy<'a>, Error> {
let proxy = zbus::ProxyBuilder::new_bare(connection)
.interface("org.freedesktop.portal.FileTransfer")?
.path(PATH)?
.destination(DESTINATION)?
.build()
.await?;
Ok(Self(proxy))
}
pub fn inner(&self) -> &zbus::Proxy<'_> {
&self.0
}
#[doc(alias = "AddFiles")]
pub async fn add_files(&self, key: &str, fds: &[&impl AsRawFd]) -> Result<(), Error> {
let options: HashMap<&str, Value<'_>> = HashMap::new();
let files: Vec<Fd> = fds.iter().map(|f| Fd::from(f.as_raw_fd())).collect();
call_method(self.inner(), "AddFiles", &(key, files, options)).await
}
#[doc(alias = "RetrieveFiles")]
pub async fn retrieve_files(&self, key: &str) -> Result<Vec<String>, Error> {
let options: HashMap<&str, Value<'_>> = HashMap::new();
call_method(self.inner(), "RetrieveFiles", &(key, options)).await
}
pub async fn start_transfer(&self, writeable: bool, auto_stop: bool) -> Result<String, Error> {
let options = TransferOptions::default()
.writeable(writeable)
.auto_stop(auto_stop);
call_method(self.inner(), "StartTransfer", &(options)).await
}
#[doc(alias = "StopTransfer")]
pub async fn stop_transfer(&self, key: &str) -> Result<(), Error> {
call_method(self.inner(), "StopTransfer", &(key)).await
}
#[doc(alias = "TransferClosed")]
pub async fn transfer_closed(&self) -> Result<String, Error> {
receive_signal(self.inner(), "TransferClosed").await
}
}