1#![deny(clippy::all, clippy::pedantic, clippy::cargo, unsafe_code, rustdoc::all)]
2#![allow(clippy::module_name_repetitions)]
3#![allow(clippy::multiple_crate_versions)]
4
5#[macro_use]
13extern crate static_assertions;
14#[macro_use]
15pub(crate) mod macros;
16
17pub mod action;
18#[cfg(feature = "wrappers")]
19pub use crate::events::event_wrappers::{
20 CacheEvents, DocumentEvents, Event, EventListenerEvents, FocusEvents, KeyboardEvents,
21 MouseEvents, ObjectEvents, TerminalEvents, WindowEvents,
22};
23pub use action::Action;
24pub mod object_match;
25pub use object_match::{MatchType, ObjectMatchRule, SortOrder, TreeTraversalType};
26pub mod object_ref;
27pub use object_ref::ObjectRef;
28pub mod operation;
29pub use operation::Operation;
30pub mod interface;
31pub use interface::{Interface, InterfaceSet};
32pub mod state;
33pub use state::{State, StateSet};
34pub mod cache;
35pub use cache::{CacheItem, LegacyCacheItem};
36pub mod error;
37pub use error::AtspiError;
38pub mod events;
39pub use events::{EventProperties, EventTypeProperties};
40mod role;
41pub use role::Role;
42mod relation_type;
43pub use relation_type::RelationType;
44
45use serde::{Deserialize, Serialize};
46use zvariant::Type;
47
48pub type Result<T> = std::result::Result<T, AtspiError>;
49
50#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
55pub struct TextSelection {
56 start_obj: ObjectRef,
58 start_idx: i32,
60 end_obj: ObjectRef,
62 end_idx: i32,
64 start_is_active: bool,
69}
70
71#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
72#[repr(u32)]
73pub enum CoordType {
75 Screen,
77 Window,
79 Parent,
81}
82
83#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Type)]
84#[repr(u32)]
85pub enum ClipType {
87 Neither,
89 Min,
91 Max,
93 Both,
95}
96
97#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Type)]
98#[repr(u32)]
99pub enum Granularity {
101 Char,
103 Word,
105 Sentence,
107 Line,
109 Paragraph,
111}
112
113#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
128pub enum Layer {
129 Invalid,
131 Background,
134 Canvas,
137 Widget,
139 Mdi,
144 Popup,
146 Overlay,
148 Window,
150}
151
152#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
154pub enum ScrollType {
155 TopLeft,
157 BottomRight,
159 TopEdge,
161 BottomEdge,
163 LeftEdge,
165 RightEdge,
167 Anywhere,
169}
170
171#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize, Type)]
179#[repr(i32)]
180pub enum Politeness {
181 #[default]
183 None = 0,
184 Polite = 1,
186 Assertive = 2,
188}
189
190impl TryFrom<i32> for Politeness {
191 type Error = AtspiError;
192
193 fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
194 match value {
195 0 => Ok(Politeness::None),
196 1 => Ok(Politeness::Polite),
197 2 => Ok(Politeness::Assertive),
198 _ => Err(AtspiError::Conversion("Unknown Politeness variant")),
199 }
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206 use std::str::FromStr;
207 use zbus_lockstep::{
208 method_args_signature, method_return_signature, signal_body_type_signature,
209 };
210 use zvariant::Signature;
211
212 #[test]
213 fn convert_i32_to_live() {
214 assert_eq!(Politeness::None, Politeness::try_from(0).unwrap());
215 assert_eq!(Politeness::Polite, Politeness::try_from(1).unwrap());
216 assert_eq!(Politeness::Assertive, Politeness::try_from(2).unwrap());
217 assert!(Politeness::try_from(3).is_err());
218 assert!(Politeness::try_from(-1).is_err());
219 }
220
221 #[test]
222 fn validate_live_signature() {
223 let signature = signal_body_type_signature!("Announcement");
224 let politeness_signature_str = &signature.to_string_no_parens();
225 let politeness_signature = Signature::from_str(&politeness_signature_str.as_str()[1..2])
226 .expect("Valid signature pattern");
227 assert_eq!(*<Politeness as Type>::SIGNATURE, politeness_signature);
228 }
229
230 #[test]
231 fn validate_scroll_type_signature() {
232 let signature = method_args_signature!(member: "ScrollTo", interface: "org.a11y.atspi.Component", argument: "type");
233 assert_eq!(*<ScrollType as Type>::SIGNATURE, signature);
234 }
235
236 #[test]
237 fn validate_layer_signature() {
238 let signature = method_return_signature!("GetLayer");
239 assert_eq!(*<Layer as Type>::SIGNATURE, signature);
240 }
241
242 #[test]
243 fn validate_granularity_signature() {
244 let signature = method_args_signature!(member: "GetStringAtOffset", interface: "org.a11y.atspi.Text", argument: "granularity");
245 assert_eq!(*<Granularity as Type>::SIGNATURE, signature);
246 }
247
248 #[test]
249 fn validate_clip_type_signature() {
250 let signature = method_args_signature!(member: "GetTextAtOffset", interface: "org.a11y.atspi.Text", argument: "type");
251 assert_eq!(*<ClipType as Type>::SIGNATURE, signature);
252 }
253
254 #[test]
255 fn validate_coord_type_signature() {
256 let signature = method_args_signature!(member: "GetImagePosition", interface: "org.a11y.atspi.Image", argument: "coordType");
257 assert_eq!(*<CoordType as Type>::SIGNATURE, signature);
258 }
259
260 #[test]
261 fn validate_match_type_signature() {
262 let rule_signature = method_args_signature!(member: "GetMatchesTo", interface: "org.a11y.atspi.Collection", argument: "rule");
263 let match_type_signature_str = rule_signature.to_string();
264 let match_type_signature = Signature::from_str(&match_type_signature_str.as_str()[3..4])
265 .expect("Valid signature pattern");
266 assert_eq!(*<MatchType as Type>::SIGNATURE, match_type_signature);
267 }
268
269 #[test]
270 fn validate_text_selection_signature() {
271 let selection_signature = method_args_signature!(member: "GetTextSelections", interface: "org.a11y.atspi.Document", argument: "selections");
272 let selection_signature_str = selection_signature.to_string();
273 let selection_signature = Signature::from_str(&selection_signature_str.as_str()[1..])
274 .expect("Valid signature pattern");
275 assert_eq!(*<TextSelection as Type>::SIGNATURE, selection_signature);
277 }
278}