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