ashpd/desktop/
open_uri.rs1use std::os::fd::AsFd;
55
56use url::Url;
57use zbus::zvariant::{Fd, SerializeDict, Type};
58
59use super::{HandleToken, Request};
60use crate::{proxy::Proxy, ActivationToken, Error, WindowIdentifier};
61
62#[derive(SerializeDict, Type, Debug, Default)]
63#[zvariant(signature = "dict")]
64struct OpenDirOptions {
65 handle_token: HandleToken,
66 activation_token: Option<ActivationToken>,
67}
68
69#[derive(SerializeDict, Type, Debug, Default)]
70#[zvariant(signature = "dict")]
71struct OpenFileOptions {
72 handle_token: HandleToken,
73 writeable: Option<bool>,
74 ask: Option<bool>,
75 activation_token: Option<ActivationToken>,
76}
77
78#[derive(Debug)]
79struct OpenURIProxy<'a>(Proxy<'a>);
80
81impl<'a> OpenURIProxy<'a> {
82 pub async fn new() -> Result<OpenURIProxy<'a>, Error> {
83 let proxy = Proxy::new_desktop("org.freedesktop.portal.OpenURI").await?;
84 Ok(Self(proxy))
85 }
86
87 pub async fn open_directory(
88 &self,
89 identifier: Option<&WindowIdentifier>,
90 directory: &impl AsFd,
91 options: OpenDirOptions,
92 ) -> Result<Request<()>, Error> {
93 let identifier = identifier.map(|i| i.to_string()).unwrap_or_default();
94 self.0
95 .empty_request(
96 &options.handle_token,
97 "OpenDirectory",
98 &(&identifier, Fd::from(directory), &options),
99 )
100 .await
101 }
102
103 pub async fn open_file(
104 &self,
105 identifier: Option<&WindowIdentifier>,
106 file: &impl AsFd,
107 options: OpenFileOptions,
108 ) -> Result<Request<()>, Error> {
109 let identifier = identifier.map(|i| i.to_string()).unwrap_or_default();
110 self.0
111 .empty_request(
112 &options.handle_token,
113 "OpenFile",
114 &(&identifier, Fd::from(file), &options),
115 )
116 .await
117 }
118
119 pub async fn open_uri(
120 &self,
121 identifier: Option<&WindowIdentifier>,
122 uri: &url::Url,
123 options: OpenFileOptions,
124 ) -> Result<Request<()>, Error> {
125 let identifier = identifier.map(|i| i.to_string()).unwrap_or_default();
126 self.0
127 .empty_request(
128 &options.handle_token,
129 "OpenURI",
130 &(&identifier, uri, &options),
131 )
132 .await
133 }
134}
135
136impl<'a> std::ops::Deref for OpenURIProxy<'a> {
137 type Target = zbus::Proxy<'a>;
138
139 fn deref(&self) -> &Self::Target {
140 &self.0
141 }
142}
143
144#[derive(Debug, Default)]
145#[doc(alias = "org.freedesktop.portal.OpenURI")]
146#[doc(alias = "xdp_portal_open_uri")]
147pub struct OpenFileRequest {
151 identifier: Option<WindowIdentifier>,
152 options: OpenFileOptions,
153}
154
155impl OpenFileRequest {
156 #[must_use]
157 pub fn identifier(mut self, identifier: impl Into<Option<WindowIdentifier>>) -> Self {
159 self.identifier = identifier.into();
160 self
161 }
162
163 #[must_use]
164 pub fn writeable(mut self, writeable: impl Into<Option<bool>>) -> Self {
166 self.options.writeable = writeable.into();
167 self
168 }
169
170 #[must_use]
171 pub fn ask(mut self, ask: impl Into<Option<bool>>) -> Self {
173 self.options.ask = ask.into();
174 self
175 }
176
177 #[must_use]
179 pub fn activation_token(
180 mut self,
181 activation_token: impl Into<Option<ActivationToken>>,
182 ) -> Self {
183 self.options.activation_token = activation_token.into();
184 self
185 }
186
187 pub async fn send_file(self, file: &impl AsFd) -> Result<Request<()>, Error> {
189 let proxy = OpenURIProxy::new().await?;
190 proxy
191 .open_file(self.identifier.as_ref(), file, self.options)
192 .await
193 }
194
195 pub async fn send_uri(self, uri: &Url) -> Result<Request<()>, Error> {
197 let proxy = OpenURIProxy::new().await?;
198 proxy
199 .open_uri(self.identifier.as_ref(), uri, self.options)
200 .await
201 }
202}
203
204#[derive(Debug, Default)]
205#[doc(alias = "xdp_portal_open_directory")]
206#[doc(alias = "org.freedesktop.portal.OpenURI")]
207pub struct OpenDirectoryRequest {
211 identifier: Option<WindowIdentifier>,
212 options: OpenDirOptions,
213}
214
215impl OpenDirectoryRequest {
216 #[must_use]
217 pub fn identifier(mut self, identifier: impl Into<Option<WindowIdentifier>>) -> Self {
219 self.identifier = identifier.into();
220 self
221 }
222
223 #[must_use]
225 pub fn activation_token(
226 mut self,
227 activation_token: impl Into<Option<ActivationToken>>,
228 ) -> Self {
229 self.options.activation_token = activation_token.into();
230 self
231 }
232
233 pub async fn send(self, directory: &impl AsFd) -> Result<Request<()>, Error> {
235 let proxy = OpenURIProxy::new().await?;
236 proxy
237 .open_directory(self.identifier.as_ref(), directory, self.options)
238 .await
239 }
240}