Skip to main content

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}