From 2786202b47b636508d0b56167a9f52dbcae99394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Thu, 29 Jan 2026 12:27:55 +0100 Subject: [PATCH 1/2] docs(features): clarify driver and device requirements --- src/features.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/features.rs b/src/features.rs index 7c55261..432925a 100644 --- a/src/features.rs +++ b/src/features.rs @@ -13,6 +13,14 @@ where /// /// If `self` is a single feature and multiple features are returned, `self` requires only one of them. /// + /// # Driver Requirements + /// + /// The driver MUST NOT accept a feature which requires another feature which was not accepted. + /// + /// # Device Requirements + /// + /// The device MUST NOT offer a feature which requires another feature which was not offered. + /// /// # Examples /// /// ``` From a7517a15914ad8fcd6e53fc722fdf08675cb4af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Thu, 29 Jan 2026 12:39:57 +0100 Subject: [PATCH 2/2] feat(features): add `recommendations` and `recommendations_satisfied` --- src/features.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/features.rs b/src/features.rs index 432925a..d85bc99 100644 --- a/src/features.rs +++ b/src/features.rs @@ -60,6 +60,50 @@ where .filter(|requirements| !requirements.is_empty()) .all(|requirements| self.intersects(requirements)) } + + /// Returns the feature that this feature recommends. + /// + /// If `self` is a single feature and multiple features are returned, `self` recommendns only one of them. + /// + /// # Driver Requirements + /// + /// The driver SHOULD NOT accept a feature which recommends another feature which was not accepted. + /// + /// # Device Requirements + /// + /// The device SHOULD NOT offer a feature which recommends another feature which was not offered. + /// + /// # Examples + /// + /// ``` + /// # use virtio_spec as virtio; + /// use virtio::FeatureBits; + /// + /// assert_eq!( + /// virtio::net::F::HASH_REPORT.recommendations(), + /// virtio::net::F::CTRL_VQ + /// ); + /// ``` + fn recommendations(&self) -> Self { + Self::empty() + } + + /// Returns `true` if all internal feature recommendations are satisfied. + /// + /// # Examples + /// + /// ``` + /// # use virtio_spec as virtio; + /// use virtio::FeatureBits; + /// + /// assert!((virtio::net::F::HASH_REPORT | virtio::net::F::CTRL_VQ).recommendations_satisfied()); + /// ``` + fn recommendations_satisfied(&self) -> bool { + self.iter() + .map(|feature| feature.recommendations()) + .filter(|recommendations| !recommendations.is_empty()) + .all(|recommendations| self.intersects(recommendations)) + } } endian_bitflags! { @@ -496,6 +540,21 @@ pub mod net { requirements } + + fn recommendations(&self) -> Self { + let mut recommendations = Self::empty(); + + for feature in self.iter() { + let recommendation = match feature { + Self::HASH_REPORT => Self::CTRL_VQ, + Self::CTRL_RX_EXTRA => Self::CTRL_VQ, + _ => Self::empty(), + }; + recommendations.insert(recommendation); + } + + recommendations + } } }