accesskit_unix/atspi/interfaces/
accessible.rs

1// Copyright 2022 The AccessKit Authors. All rights reserved.
2// Licensed under the Apache License, Version 2.0 (found in
3// the LICENSE-APACHE file) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6use std::collections::HashMap;
7
8use accesskit_atspi_common::{NodeIdOrRoot, PlatformNode, PlatformRoot};
9use atspi::{Interface, InterfaceSet, Role, StateSet};
10use zbus::{fdo, interface, names::OwnedUniqueName};
11
12use super::map_root_error;
13use crate::atspi::{ObjectId, OwnedObjectAddress};
14
15pub(crate) struct NodeAccessibleInterface {
16    bus_name: OwnedUniqueName,
17    node: PlatformNode,
18}
19
20impl NodeAccessibleInterface {
21    pub fn new(bus_name: OwnedUniqueName, node: PlatformNode) -> Self {
22        Self { bus_name, node }
23    }
24
25    fn map_error(&self) -> impl '_ + FnOnce(accesskit_atspi_common::Error) -> fdo::Error {
26        |error| crate::util::map_error_from_node(&self.node, error)
27    }
28}
29
30#[interface(name = "org.a11y.atspi.Accessible")]
31impl NodeAccessibleInterface {
32    #[zbus(property)]
33    fn name(&self) -> fdo::Result<String> {
34        self.node.name().map_err(self.map_error())
35    }
36
37    #[zbus(property)]
38    fn description(&self) -> fdo::Result<String> {
39        self.node.description().map_err(self.map_error())
40    }
41
42    #[zbus(property)]
43    fn parent(&self) -> fdo::Result<OwnedObjectAddress> {
44        self.node.parent().map_err(self.map_error()).map(|parent| {
45            match parent {
46                NodeIdOrRoot::Node(node) => ObjectId::Node {
47                    adapter: self.node.adapter_id(),
48                    node,
49                },
50                NodeIdOrRoot::Root => ObjectId::Root,
51            }
52            .to_address(self.bus_name.inner())
53        })
54    }
55
56    #[zbus(property)]
57    fn child_count(&self) -> fdo::Result<i32> {
58        self.node.child_count().map_err(self.map_error())
59    }
60
61    #[zbus(property)]
62    fn locale(&self) -> &str {
63        ""
64    }
65
66    #[zbus(property)]
67    fn accessible_id(&self) -> fdo::Result<String> {
68        self.node.accessible_id().map_err(self.map_error())
69    }
70
71    fn get_child_at_index(&self, index: i32) -> fdo::Result<(OwnedObjectAddress,)> {
72        let index = index
73            .try_into()
74            .map_err(|_| fdo::Error::InvalidArgs("Index can't be negative.".into()))?;
75        let child = self
76            .node
77            .child_at_index(index)
78            .map_err(self.map_error())?
79            .map(|child| ObjectId::Node {
80                adapter: self.node.adapter_id(),
81                node: child,
82            });
83        Ok(super::optional_object_address(&self.bus_name, child))
84    }
85
86    fn get_children(&self) -> fdo::Result<Vec<OwnedObjectAddress>> {
87        self.node
88            .map_children(|child| {
89                ObjectId::Node {
90                    adapter: self.node.adapter_id(),
91                    node: child,
92                }
93                .to_address(self.bus_name.inner())
94            })
95            .map_err(self.map_error())
96    }
97
98    fn get_index_in_parent(&self) -> fdo::Result<i32> {
99        self.node.index_in_parent().map_err(self.map_error())
100    }
101
102    fn get_role(&self) -> fdo::Result<Role> {
103        self.node.role().map_err(self.map_error())
104    }
105
106    fn get_localized_role_name(&self) -> fdo::Result<String> {
107        self.node.localized_role_name().map_err(self.map_error())
108    }
109
110    fn get_state(&self) -> StateSet {
111        self.node.state()
112    }
113
114    fn get_attributes(&self) -> fdo::Result<HashMap<&str, String>> {
115        self.node.attributes().map_err(self.map_error())
116    }
117
118    fn get_application(&self) -> (OwnedObjectAddress,) {
119        (ObjectId::Root.to_address(self.bus_name.inner()),)
120    }
121
122    fn get_interfaces(&self) -> fdo::Result<InterfaceSet> {
123        self.node.interfaces().map_err(self.map_error())
124    }
125}
126
127pub(crate) struct RootAccessibleInterface {
128    bus_name: OwnedUniqueName,
129    root: PlatformRoot,
130}
131
132impl RootAccessibleInterface {
133    pub fn new(bus_name: OwnedUniqueName, root: PlatformRoot) -> Self {
134        Self { bus_name, root }
135    }
136}
137
138#[interface(name = "org.a11y.atspi.Accessible")]
139impl RootAccessibleInterface {
140    #[zbus(property)]
141    fn name(&self) -> fdo::Result<String> {
142        self.root.name().map_err(map_root_error)
143    }
144
145    #[zbus(property)]
146    fn description(&self) -> &str {
147        ""
148    }
149
150    #[zbus(property)]
151    fn parent(&self) -> OwnedObjectAddress {
152        OwnedObjectAddress::null()
153    }
154
155    #[zbus(property)]
156    fn child_count(&self) -> fdo::Result<i32> {
157        self.root.child_count().map_err(map_root_error)
158    }
159
160    #[zbus(property)]
161    fn locale(&self) -> &str {
162        ""
163    }
164
165    #[zbus(property)]
166    fn accessible_id(&self) -> &str {
167        ""
168    }
169
170    fn get_child_at_index(&self, index: i32) -> fdo::Result<(OwnedObjectAddress,)> {
171        let index = index
172            .try_into()
173            .map_err(|_| fdo::Error::InvalidArgs("Index can't be negative.".into()))?;
174        let child = self
175            .root
176            .child_id_at_index(index)
177            .map_err(map_root_error)?
178            .map(|(adapter, node)| ObjectId::Node { adapter, node });
179        Ok(super::optional_object_address(&self.bus_name, child))
180    }
181
182    fn get_children(&self) -> fdo::Result<Vec<OwnedObjectAddress>> {
183        self.root
184            .map_child_ids(|(adapter, node)| {
185                ObjectId::Node { adapter, node }.to_address(self.bus_name.inner())
186            })
187            .map_err(map_root_error)
188    }
189
190    fn get_index_in_parent(&self) -> i32 {
191        -1
192    }
193
194    fn get_role(&self) -> Role {
195        Role::Application
196    }
197
198    fn get_state(&self) -> StateSet {
199        StateSet::empty()
200    }
201
202    fn get_application(&self) -> (OwnedObjectAddress,) {
203        (ObjectId::Root.to_address(self.bus_name.inner()),)
204    }
205
206    fn get_interfaces(&self) -> InterfaceSet {
207        InterfaceSet::new(Interface::Accessible | Interface::Application)
208    }
209}