Skip to main content

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}