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 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}