use std::collections::HashSet;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Feature {
Init,
Version,
Update,
Docs,
Mcp,
Doctor,
Ai,
Telemetry,
Config,
Changelog,
Credentials,
}
impl Feature {
#[must_use]
pub fn defaults() -> Features {
Features::builder().build()
}
#[must_use]
pub const fn all() -> &'static [Self] {
&[
Self::Init,
Self::Version,
Self::Update,
Self::Docs,
Self::Mcp,
Self::Doctor,
Self::Ai,
Self::Telemetry,
Self::Config,
Self::Changelog,
Self::Credentials,
]
}
}
#[derive(Debug, Clone)]
pub struct Features {
enabled: HashSet<Feature>,
}
impl Default for Features {
fn default() -> Self {
Self::builder().build()
}
}
impl Features {
#[must_use]
pub fn is_enabled(&self, feature: Feature) -> bool {
self.enabled.contains(&feature)
}
#[must_use]
pub fn builder() -> FeaturesBuilder {
FeaturesBuilder::new()
}
pub fn iter(&self) -> impl Iterator<Item = Feature> + '_ {
self.enabled.iter().copied()
}
}
#[derive(Debug, Default)]
pub struct FeaturesBuilder {
enabled: HashSet<Feature>,
}
impl FeaturesBuilder {
#[must_use]
pub fn new() -> Self {
Self {
enabled: [
Feature::Init,
Feature::Version,
Feature::Update,
Feature::Docs,
Feature::Mcp,
Feature::Doctor,
Feature::Credentials,
Feature::Telemetry,
Feature::Config,
]
.into_iter()
.collect(),
}
}
#[must_use]
pub fn none() -> Self {
Self { enabled: HashSet::new() }
}
#[must_use]
pub fn enable(mut self, feature: Feature) -> Self {
self.enabled.insert(feature);
self
}
#[must_use]
pub fn disable(mut self, feature: Feature) -> Self {
self.enabled.remove(&feature);
self
}
#[must_use]
pub fn build(self) -> Features {
Features { enabled: self.enabled }
}
}