protocol/capability.rs
1//! The capability set an agent advertises in its hello.
2
3wire_flags! {
4 /// What an agent implements, advertised in its hello as a `u32` bitmask.
5 /// The host refuses a request whose method needs a capability the agent
6 /// did not advertise ([`crate::message::Method::required_capability`]).
7 pub struct Capabilities;
8 /// Tree reads: `snapshot`.
9 TREE = 0, "tree";
10 /// Input injection: `tap`, `swipe`, `key`.
11 INPUT = 1, "input";
12 /// Screenshots: `screenshot`.
13 SCREENSHOT = 2, "screenshot";
14 /// Frame streaming: `frames_start`, `frames_stop`.
15 FRAMES = 3, "frames";
16 /// Change events on the tree, window and lifecycle streams, and `resync`.
17 EVENTS = 4, "events";
18 /// Direct text setting: `text_set`.
19 TEXT_SET = 5, "text_set";
20 /// Nodes' bounds read again past the platform's node cache: `bounds`.
21 BOUNDS = 6, "bounds";
22}
23
24impl Capabilities {
25 /// The empty set.
26 pub const NONE: Capabilities = Capabilities::EMPTY;
27
28 /// A human description of the capabilities in `self`, such as
29 /// `frame streaming`, for error messages.
30 pub fn label(self) -> String {
31 const LABELS: [(Capabilities, &str); 7] = [
32 (Capabilities::TREE, "tree reads"),
33 (Capabilities::INPUT, "input injection"),
34 (Capabilities::SCREENSHOT, "screenshots"),
35 (Capabilities::FRAMES, "frame streaming"),
36 (Capabilities::EVENTS, "change events"),
37 (Capabilities::TEXT_SET, "direct text setting"),
38 (Capabilities::BOUNDS, "bounds probes"),
39 ];
40 let labels: Vec<&str> = LABELS
41 .iter()
42 .filter(|(cap, _)| self.contains(*cap))
43 .map(|(_, label)| *label)
44 .collect();
45 if labels.is_empty() {
46 self.to_string()
47 } else {
48 labels.join(" and ")
49 }
50 }
51}