feature_set/
feature_set.rs1use std::collections::BTreeMap;
2use std::fmt;
3
4use crate::action::Action;
5use crate::feature::Feature;
6use crate::Provide;
7use crate::Require;
8
9#[derive(Debug, Clone)]
11pub struct FeatureSet {
12 features: BTreeMap<(&'static str, u64), Feature>,
13}
14
15impl FeatureSet {
16 pub fn from_provides<'a>(provides: impl IntoIterator<Item = &'a Action<Provide>>) -> Self {
18 let mut features = BTreeMap::new();
19 for a in provides {
20 match a {
21 Action::Add(p) => {
22 let feature = p.feature();
23 let key = (feature.name(), feature.ver());
24
25 assert!(
26 !features.contains_key(&key),
27 "duplicate feature: {:?}",
28 feature
29 );
30
31 features.insert(key, feature.clone());
32 }
33 Action::Delete(p) => {
34 let feature = p.feature();
35 let key = (feature.name(), feature.ver());
36
37 assert!(
38 features.contains_key(&key),
39 "feature not found: {:?}",
40 feature
41 );
42
43 features.remove(&key);
44 }
45 }
46 }
47
48 Self { features }
49 }
50
51 pub fn from_required<'a>(
56 required: impl IntoIterator<Item = &'a Action<Require>>,
57 include_optional: bool,
58 ) -> Self {
59 let mut features = BTreeMap::new();
60 for a in required {
61 match a {
62 Action::Add(p) => {
63 if !include_optional && p.optional() {
64 continue;
65 }
66
67 let feature = p.feature();
68 let key = (feature.name(), feature.ver());
69
70 assert!(
71 !features.contains_key(&key),
72 "duplicate feature: {:?}",
73 feature
74 );
75
76 features.insert(key, feature.clone());
77 }
78 Action::Delete(p) => {
79 let feature = p.feature();
80 let key = (feature.name(), feature.ver());
81
82 assert!(
83 features.contains_key(&key),
84 "feature not found: {:?}",
85 feature
86 );
87
88 features.remove(&(feature.name(), feature.ver()));
89 }
90 }
91 }
92
93 Self { features }
94 }
95
96 pub fn contains(&self, name_ver: (&str, u64)) -> bool {
97 self.features.contains_key(&name_ver)
98 }
99}
100
101impl fmt::Display for FeatureSet {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 write!(
104 f,
105 "{}",
106 self.features
107 .keys()
108 .map(|(n, v)| { format!("{}:v{:}", n, v) })
109 .collect::<Vec<_>>()
110 .join(", ")
111 )
112 }
113}