use std::collections::BTreeSet;
use isoloom_manifest::{HostOs, Provider};
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Scope {
pub(crate) host: HostOs,
pub(crate) provider: Option<String>,
}
impl Scope {
pub(crate) fn admits(&self, hosts: &BTreeSet<HostOs>, providers: &BTreeSet<Provider>) -> bool {
let host = hosts.is_empty() || hosts.contains(&self.host);
let provider = providers.is_empty() || self.provider.as_deref().is_some_and(|p| providers.iter().any(|q| provider_id(*q) == p));
host && provider
}
}
pub(crate) fn provider_id(p: Provider) -> String {
serde_json::to_value(p).ok().and_then(|v| v.as_str().map(str::to_owned)).unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_scope_admits_what_names_its_host_and_provider_or_names_none() {
let esxi = Scope {
host: HostOs::Macos,
provider: Some("vmware_esxi".into()),
};
let (any_host, any_provider) = (BTreeSet::new(), BTreeSet::new());
assert!(esxi.admits(&any_host, &any_provider));
assert!(esxi.admits(&BTreeSet::from([HostOs::Macos]), &BTreeSet::from([Provider::VmwareEsxi])));
assert!(!esxi.admits(&BTreeSet::from([HostOs::Windows]), &any_provider));
assert!(!esxi.admits(&any_host, &BTreeSet::from([Provider::Virtualbox])));
let no_provider = Scope {
host: HostOs::Linux,
provider: None,
};
assert!(!no_provider.admits(&any_host, &BTreeSet::from([Provider::Virtualbox])));
assert_eq!(provider_id(Provider::VmwareDesktop), "vmware_desktop");
}
}