hidpp/feature/mod.rs
1//! Specific device feature implementations.
2
3use std::{any::Any, sync::Arc};
4
5use crate::channel::HidppChannel;
6
7pub mod device_friendly_name;
8pub mod device_information;
9pub mod device_type_and_name;
10pub mod feature_set;
11pub mod hires_wheel;
12pub mod registry;
13pub mod root;
14pub mod smartshift;
15pub mod thumbwheel;
16pub mod unified_battery;
17pub mod wireless_device_status;
18
19/// Represents a concrete implementation of a HID++2.0 device feature.
20pub trait Feature: Any + Send + Sync {}
21
22/// Represents a [`Feature`] that can be instantiated automatically.
23pub trait CreatableFeature: Feature {
24 /// The protocol ID of the implemented feature.
25 const ID: u16;
26
27 /// The version of the feature the implementation starts to support.
28 const STARTING_VERSION: u8;
29
30 /// Creates a new instance of the feature implementation.
31 fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self;
32}
33
34/// Represents a [`Feature`] that emits events of type `T`.
35pub trait EmittingFeature<T>: Feature {
36 /// Creates a receiver that is being notified whenever a new event of type
37 /// `T` is emitted by the feature.
38 fn listen(&self) -> async_channel::Receiver<T>;
39}
40
41/// A bitfield describing some properties of a feature.
42///
43/// Documentation is taken from <https://drive.google.com/file/d/1ULmw9uJL8b8iwwUo5xjSS9F5Zvno-86y/view>.
44#[derive(Clone, Copy, Hash, Debug)]
45#[cfg_attr(feature = "serde", derive(serde::Serialize))]
46#[non_exhaustive]
47pub struct FeatureType {
48 /// An obsolete feature is a feature that has been replaced by a newer one,
49 /// but is advertised in order for older SWs to still be able to support the
50 /// feature (in case the old SW does not know yet the newer one).
51 pub obsolete: bool,
52
53 /// A SW hidden feature is a feature that should not be known/managed/used
54 /// by end user configuration SW. The host should ignore this type of
55 /// features.
56 pub hidden: bool,
57
58 /// A hidden feature that has been disabled for user software. Used for
59 /// internal testing and manufacturing.
60 pub engineering: bool,
61
62 /// A manufacturing feature that can be permanently deactivated. It is
63 /// usually also hidden and engineering.
64 ///
65 /// This field was added in feature version 2 and will be `false` for all
66 /// older versions.
67 pub manufacturing_deactivatable: bool,
68
69 /// A compliance feature that can be permanently deactivated. It is usually
70 /// also hidden and engineering.
71 ///
72 /// This field was added in feature version 2 and will be `false` for all
73 /// older versions.
74 pub compliance_deactivatable: bool,
75}
76
77impl From<u8> for FeatureType {
78 fn from(value: u8) -> Self {
79 Self {
80 obsolete: value & (1 << 7) != 0,
81 hidden: value & (1 << 6) != 0,
82 engineering: value & (1 << 5) != 0,
83 manufacturing_deactivatable: value & (1 << 4) != 0,
84 compliance_deactivatable: value & (1 << 3) != 0,
85 }
86 }
87}
88
89impl From<FeatureType> for u8 {
90 fn from(value: FeatureType) -> Self {
91 let mut raw = 0;
92
93 if value.obsolete {
94 raw |= 1 << 7
95 }
96 if value.hidden {
97 raw |= 1 << 6
98 }
99 if value.engineering {
100 raw |= 1 << 5
101 }
102 if value.manufacturing_deactivatable {
103 raw |= 1 << 4
104 }
105 if value.compliance_deactivatable {
106 raw |= 1 << 3
107 }
108
109 raw
110 }
111}