atspi_proxies/
proxy_ext.rs

1use crate::{
2	accessible::AccessibleProxy, action::ActionProxy, application::ApplicationProxy,
3	cache::CacheProxy, collection::CollectionProxy, component::ComponentProxy,
4	document::DocumentProxy, editable_text::EditableTextProxy, hyperlink::HyperlinkProxy,
5	hypertext::HypertextProxy, image::ImageProxy, selection::SelectionProxy, table::TableProxy,
6	table_cell::TableCellProxy, text::TextProxy, value::ValueProxy, AtspiError,
7};
8use atspi_common::{Interface, InterfaceSet, Result};
9
10/// Acquire the other interface proxies an object may have implemented.
11///
12/// Equip objects with conversions to proxies of the objects' implemented interfaces
13/// by extending `AccessibleProxy`.
14///
15/// The `proxies` method returns a `Proxies` struct.
16pub trait ProxyExt<'a> {
17	/// Get `Proxies` for the current object.
18	fn proxies(&self) -> impl std::future::Future<Output = Result<Proxies<'a>>>;
19}
20
21/// An object for safe conversion to the related interface proxies.
22#[derive(Clone, Debug)]
23pub struct Proxies<'a> {
24	interfaces: InterfaceSet,
25	proxy: zbus::Proxy<'a>,
26}
27
28impl<'a> ProxyExt<'a> for AccessibleProxy<'a> {
29	async fn proxies(&self) -> Result<Proxies<'a>> {
30		let iface_set: InterfaceSet = self.get_interfaces().await?;
31		let proxy = self.inner().clone();
32
33		Ok(Proxies { interfaces: iface_set, proxy })
34	}
35}
36
37impl<'a> Proxies<'a> {
38	/// Get the `Action` interface proxy.
39	///
40	/// # Errors
41	///
42	/// Returns an error if the interface is not available.
43	pub async fn action(&self) -> Result<ActionProxy<'a>> {
44		if self.interfaces.contains(Interface::Action) {
45			Ok(ActionProxy::builder(self.proxy.connection())
46				.cache_properties(zbus::proxy::CacheProperties::No)
47				.destination(self.proxy.destination())?
48				.path(self.proxy.path())?
49				.build()
50				.await?)
51		} else {
52			Err(AtspiError::InterfaceNotAvailable("Action"))
53		}
54	}
55
56	/// Get the `Application` interface proxy.
57	///
58	/// # Errors
59	///
60	/// Returns an error if the interface is not available.
61	pub async fn application(&self) -> Result<ApplicationProxy<'a>> {
62		if self.interfaces.contains(Interface::Application) {
63			Ok(ApplicationProxy::builder(self.proxy.connection())
64				.cache_properties(zbus::proxy::CacheProperties::No)
65				.destination(self.proxy.destination())?
66				.path(self.proxy.path())?
67				.build()
68				.await?)
69		} else {
70			Err(AtspiError::InterfaceNotAvailable("Application"))
71		}
72	}
73
74	/// Get the `Cache` interface proxy.
75	///
76	/// # Errors
77	///
78	/// Returns an error if the interface is not available.
79	pub async fn cache(&self) -> Result<CacheProxy<'a>> {
80		if self.interfaces.contains(Interface::Cache) {
81			Ok(CacheProxy::builder(self.proxy.connection())
82				.cache_properties(zbus::proxy::CacheProperties::No)
83				.destination(self.proxy.destination())?
84				.path(self.proxy.path())?
85				.build()
86				.await?)
87		} else {
88			Err(AtspiError::InterfaceNotAvailable("Cache"))
89		}
90	}
91
92	/// Get the `Collection` interface proxy.
93	///
94	/// # Errors
95	///
96	/// Returns an error if the interface is not available.
97	pub async fn collection(&self) -> Result<CollectionProxy<'a>> {
98		if self.interfaces.contains(Interface::Collection) {
99			Ok(CollectionProxy::builder(self.proxy.connection())
100				.cache_properties(zbus::proxy::CacheProperties::No)
101				.destination(self.proxy.destination())?
102				.path(self.proxy.path())?
103				.build()
104				.await?)
105		} else {
106			Err(AtspiError::InterfaceNotAvailable("Collection"))
107		}
108	}
109
110	/// Get the `Component` interface proxy.
111	///
112	/// # Errors
113	///
114	/// Returns an error if the interface is not available.
115	pub async fn component(&self) -> Result<ComponentProxy<'a>> {
116		if self.interfaces.contains(Interface::Component) {
117			Ok(ComponentProxy::builder(self.proxy.connection())
118				.cache_properties(zbus::proxy::CacheProperties::No)
119				.destination(self.proxy.destination())?
120				.path(self.proxy.path())?
121				.build()
122				.await?)
123		} else {
124			Err(AtspiError::InterfaceNotAvailable("Component"))
125		}
126	}
127
128	/// Get the `Document` interface proxy.
129	///
130	/// # Errors
131	///
132	/// Returns an error if the interface is not available.
133	pub async fn document(&self) -> Result<DocumentProxy<'a>> {
134		if self.interfaces.contains(Interface::Document) {
135			Ok(DocumentProxy::builder(self.proxy.connection())
136				.cache_properties(zbus::proxy::CacheProperties::No)
137				.destination(self.proxy.destination())?
138				.path(self.proxy.path())?
139				.build()
140				.await?)
141		} else {
142			Err(AtspiError::InterfaceNotAvailable("Document"))
143		}
144	}
145
146	/// Get the `EditableText` interface proxy.
147	///
148	/// # Errors
149	///
150	/// Returns an error if the interface is not available.
151	pub async fn editable_text(&self) -> Result<EditableTextProxy<'a>> {
152		if self.interfaces.contains(Interface::EditableText) {
153			Ok(EditableTextProxy::builder(self.proxy.connection())
154				.cache_properties(zbus::proxy::CacheProperties::No)
155				.destination(self.proxy.destination())?
156				.path(self.proxy.path())?
157				.build()
158				.await?)
159		} else {
160			Err(AtspiError::InterfaceNotAvailable("EditableText"))
161		}
162	}
163
164	/// Get the `Hyperlink` interface proxy.
165	///
166	/// # Errors
167	///
168	/// Returns an error if the interface is not available.
169	pub async fn hyperlink(&self) -> Result<HyperlinkProxy<'a>> {
170		if self.interfaces.contains(Interface::Hyperlink) {
171			Ok(HyperlinkProxy::builder(self.proxy.connection())
172				.cache_properties(zbus::proxy::CacheProperties::No)
173				.destination(self.proxy.destination())?
174				.path(self.proxy.path())?
175				.build()
176				.await?)
177		} else {
178			Err(AtspiError::InterfaceNotAvailable("Hyperlink"))
179		}
180	}
181
182	/// Get the `Hypertext` interface proxy.
183	///
184	/// # Errors
185	///
186	/// Returns an error if the interface is not available.
187	pub async fn hypertext(&self) -> Result<HypertextProxy<'a>> {
188		if self.interfaces.contains(Interface::Hypertext) {
189			Ok(HypertextProxy::builder(self.proxy.connection())
190				.cache_properties(zbus::proxy::CacheProperties::No)
191				.destination(self.proxy.destination())?
192				.path(self.proxy.path())?
193				.build()
194				.await?)
195		} else {
196			Err(AtspiError::InterfaceNotAvailable("Hypertext"))
197		}
198	}
199
200	/// Get the `Image` interface proxy.
201	///
202	/// # Errors
203	///
204	/// Returns an error if the interface is not available.
205	pub async fn image(&self) -> Result<ImageProxy<'a>> {
206		if self.interfaces.contains(Interface::Image) {
207			Ok(ImageProxy::builder(self.proxy.connection())
208				.cache_properties(zbus::proxy::CacheProperties::No)
209				.destination(self.proxy.destination())?
210				.path(self.proxy.path())?
211				.build()
212				.await?)
213		} else {
214			Err(AtspiError::InterfaceNotAvailable("Image"))
215		}
216	}
217
218	/// Get the `Registry` interface proxy.
219	///
220	/// # Errors
221	///
222	/// Returns an error if the interface is not available.
223	pub async fn selection(&self) -> Result<SelectionProxy<'a>> {
224		if self.interfaces.contains(Interface::Selection) {
225			Ok(SelectionProxy::builder(self.proxy.connection())
226				.cache_properties(zbus::proxy::CacheProperties::No)
227				.destination(self.proxy.destination())?
228				.path(self.proxy.path())?
229				.build()
230				.await?)
231		} else {
232			Err(AtspiError::InterfaceNotAvailable("Selection"))
233		}
234	}
235
236	/// Get the `Table` interface proxy.
237	///
238	/// # Errors
239	///
240	/// Returns an error if the interface is not available.
241	pub async fn table(&self) -> Result<TableProxy<'a>> {
242		if self.interfaces.contains(Interface::Table) {
243			Ok(TableProxy::builder(self.proxy.connection())
244				.cache_properties(zbus::proxy::CacheProperties::No)
245				.destination(self.proxy.destination())?
246				.path(self.proxy.path())?
247				.build()
248				.await?)
249		} else {
250			Err(AtspiError::InterfaceNotAvailable("Table"))
251		}
252	}
253
254	/// Get the `TableCell` interface proxy.
255	///
256	/// # Errors
257	///
258	/// Returns an error if the interface is not available.
259	pub async fn table_cell(&self) -> Result<TableCellProxy<'a>> {
260		if self.interfaces.contains(Interface::TableCell) {
261			Ok(TableCellProxy::builder(self.proxy.connection())
262				.cache_properties(zbus::proxy::CacheProperties::No)
263				.destination(self.proxy.destination())?
264				.path(self.proxy.path())?
265				.build()
266				.await?)
267		} else {
268			Err(AtspiError::InterfaceNotAvailable("TableCell"))
269		}
270	}
271
272	/// Get the `Text` interface proxy.
273	///
274	/// # Errors
275	///
276	/// Returns an error if the interface is not available.
277	pub async fn text(&self) -> Result<TextProxy<'a>> {
278		if self.interfaces.contains(Interface::Text) {
279			Ok(TextProxy::builder(self.proxy.connection())
280				.cache_properties(zbus::proxy::CacheProperties::No)
281				.destination(self.proxy.destination())?
282				.path(self.proxy.path())?
283				.build()
284				.await?)
285		} else {
286			Err(AtspiError::InterfaceNotAvailable("Text"))
287		}
288	}
289
290	/// Get the `Value` interface proxy.
291	///
292	/// # Errors
293	///
294	/// Returns an error if the interface is not available.
295	pub async fn value(&self) -> Result<ValueProxy<'a>> {
296		if self.interfaces.contains(Interface::Value) {
297			Ok(ValueProxy::builder(self.proxy.connection())
298				.cache_properties(zbus::proxy::CacheProperties::No)
299				.destination(self.proxy.destination())?
300				.path(self.proxy.path())?
301				.build()
302				.await?)
303		} else {
304			Err(AtspiError::InterfaceNotAvailable("Value"))
305		}
306	}
307}