use std::collections::BTreeMap;
use std::fmt;
use crate::action::Action;
use crate::feature::Feature;
use crate::Provide;
use crate::Require;
#[derive(Debug, Clone)]
pub struct FeatureSet {
features: BTreeMap<(&'static str, u64), Feature>,
}
impl FeatureSet {
pub fn from_provides<'a>(provides: impl IntoIterator<Item = &'a Action<Provide>>) -> Self {
let mut features = BTreeMap::new();
for a in provides {
match a {
Action::Add(p) => {
let feature = p.feature();
features.insert((feature.name(), feature.ver()), feature.clone());
}
Action::Delete(p) => {
let feature = p.feature();
features.remove(&(feature.name(), feature.ver()));
}
}
}
Self { features }
}
pub fn from_required<'a>(
required: impl IntoIterator<Item = &'a Action<Require>>,
include_optional: bool,
) -> Self {
let mut features = BTreeMap::new();
for a in required {
match a {
Action::Add(p) => {
if !include_optional && p.optional() {
continue;
}
let feature = p.feature();
features.insert((feature.name(), feature.ver()), feature.clone());
}
Action::Delete(p) => {
let feature = p.feature();
features.remove(&(feature.name(), feature.ver()));
}
}
}
Self { features }
}
pub fn contains(&self, name_ver: (&str, u64)) -> bool {
self.features.contains_key(&name_ver)
}
}
impl fmt::Display for FeatureSet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
self.features
.keys()
.map(|(n, v)| { format!("{}:v{:}", n, v) })
.collect::<Vec<_>>()
.join(", ")
)
}
}